最近在看关于拖延症的一本书《拖拉一点也无妨》,后面得出结论是自己写博客大部分处于两种状态,心情很好和心情很不好的时候。因为正常状态下感觉写博客吧,是件很麻烦的事情,不如去看看电影看看漫画啥的。最近在看漫画《进击的巨人》和《一拳超人》,感觉是两种极端,哈哈。    

最近在进行某个项目的重写工作,前后端都要重新构架重写,时间给了一个月。项目的现状大概是后端一个类有一万行左右,包含几十个方法。每个方法从一两百行到上千行不等,大部分方法是没有参数和返回值的,全局的操作几百个成员变量。业务需求不明确,没人能说得清,反正任务就是在不影响现有的功能的情况下重构+重写。现有的功能有啥?也没人能说得清。你说测试怎么验收通过?反正测试也说不清。

前端也面临着同样的情况,基本上都是全局的function凑合成的,几个文件加起来也有1万+行。同样没人能说得清到底有啥东西。咱作为光荣的“接盘侠”现在就要负责处理这些留下的宝贵遗产了。前端重写+后端重写+数据库SQL性能调校。

前端打算引入EventProxy和Seajs来重新整理了。

好吧,闲话扯到这里,现在开始继续顺带的内容了,javascript中的this

一、Javascript中的this

话说javascript中的this是个变态吧,总结一下:                

隐式的改变this的指向的方法

1.直接用括号()调用function的方式,这时this指向的是全局对象。

2.作为对象的方法调用,那么就是指向调用方法的对象。下面就是通过改变this来借用方法。

    function addToArray() {
arguments.slice = Array.prototype.slice;
var add = arguments.slice(0);
return add.concat();
}

可能有些人没看明白,咱的文章习惯打破砂锅问到底嘛,再举几个例子 :

我们知道Function类型是javascript中的顶级类型,可以定义自己的属性和方法。假如有这么一个方法

Function.prototype.test = function () {
    console.log(this === Function.prototype)
}

这种写法我相信有一点js经验的人都应该见过,这样写就可以给所有的函数实例加上了test方法,可具体是怎么实现的呢?我想很多人就说不清楚了。

上面这种写法,如果这样调用,会显示什么呢?

Function.prototype.test()

答案是 true !

这没什么好奇怪的,因为此时调用test方法的的确是Function类的prototype属性的对象。但如果你想想,如果this指向的是prototype的话,那么test方法为什么会在每个函数实例中都能调用呢?

因为我们的确不会像上面这样直接调用test方法,而是通过Function类的实例来调用test方法,这时候有东西悄悄发生了变化。没错,这就是this的指向。

如果有人还记得我上篇文章谈谈javascript中的prototype与继承的话,就知道javascript中的对象就是一个指向prototype的指针和一个自身的属性列表

所以作为函数类的实例,其实是通过指针的方式隐式借用了Function类的prototype属性中的所有方法。这时this指向的就不再是prototype对象,而是这个实例。

用代码来表示,类似于

this.test = Function.prototype.test

这里的this指向的是函数类的实例,因此调用的时候,结果就为false。

function myFunction(){}
myFunction.test()

显式的改变this的一些方法和关键字

1.call

    function addToArray() {
var add = Array.prototype.slice.call(arguments,0);
return add.concat();
}

2.apply

    function addToArray() {
var add = Array.prototype.slice.apply(arguments,[0]);
return add.concat();
}

3.bind (ECMA Script5)

它可以看做是call 和apply的延迟版本,如果不存在的话,可以这么实现

简单版本

if (!Function.prototype.bind) {
Function.prototype.bind = function (target) {
var func = this; return function () {
func.apply(target, arguments);
}
}
}

其实在ECMA Script5的规定中bind是可以预填参数的,考虑到性能的话,相对复杂一些。大部分情况下我们调用bind只是希望改变this的作用域,如果全部调用了slice和concat方法,那么性能就会相对不好。根据arguments的length不同,可以分2种绑定一共4种调用的case,在大部分情况下去获取更好的性能。

if (!Function.prototype.bind) {
(function () {
var slice = Array.prototype.slice; Function.prototype.bind = function (target) {
var func = this; if (arguments.length > 1) {
var args = slice.call(arguments, 1); return function () {
var allArgs = args; if (arguments.length > 0) {
allArgs = args.concat(slice.call(arguments));
} return func.apply(target, allArgs);
};
} return function () {
if (arguments.length > 0) {
return func.apply(target, arguments);
} return func.call(target);
};
};
}());
}

牢骚与javascript中的this的更多相关文章

  1. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  2. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  3. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

  4. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  5. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  6. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  7. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  8. 简单分析JavaScript中的面向对象

    初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...

  9. Javascript中的valueOf与toString

    基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...

随机推荐

  1. C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)

    C++11 并发指南已经写了 5 章,前五章重点介绍了多线程编程方面的内容,但大部分内容只涉及多线程.互斥量.条件变量和异步编程相关的 API,C++11 程序员完全可以不必知道这些 API 在底层是 ...

  2. Eclipse在线安装SVN

    一.SVN在线安装 下面为在线安装SVN插件.以下是在线安装步骤: 其中http://subclipse.tigris.org/update_1.10.x是最新版本的SVN插件的下载站点[subcli ...

  3. 编写高质量代码改善C#程序的157个建议读书笔记【11-20】

    章节索引 建议11:区别对待 == 和Equals 建议12:重写Equals也要重写GetHashCode 建议13:为类型输出格式化字符串 建议14:正确实现浅拷贝和深拷贝 建议15:使用dyna ...

  4. C语言中的内存分配与释放

    C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...

  5. 为什么Web 设计会‘死’?

    高质量的Web 模板,成熟的Design Pattern,人工智能的引用,移动技术的冲击是否标志着Web Design 结束的时代已经到来? Web Design 最终也未避免与“死亡”这个词的关联, ...

  6. Web开发者的六个代码调试平台

    代码调试平台是Web开发者进行开发.测试.分享.协作和交流的网络应用,它们支持实时的编辑.预览HTML.CSS和JavaScript的客户端代码.这些代码调试平台最值得称道的地方在于,它们中的大多数都 ...

  7. piwik流量统计系统搭建(apache2.4+piwik+mysql5.6+php5.6.14)

    Piwik: 开放源代码的Web统计软件 Piwik是一个PHP和MySQL的开放源代码的Web统计软件. 它给你一些关于你的网站的实用统计报告,比如网页浏览人数, 访问最多的页面, 搜索引擎关键词等 ...

  8. SQL 2012 发布与订阅实现数据同步 图解(解决 错误22022)

    概念参见:https://msdn.microsoft.com/zh-cn/library/ms151170.aspx 推送订阅 对于推送订阅,发布服务器将更改传播到订阅服务器,而无需订阅服务器发出请 ...

  9. TF Boys (TensorFlow Boys ) 养成记(一)

    本资料是在Ubuntu14.0.4版本下进行,用来进行图像处理,所以只介绍关于图像处理部分的内容,并且默认TensorFlow已经配置好,如果没有配置好,请参考官方文档配置安装,推荐用pip安装.关于 ...

  10. phpweb成品网站最新版(注入、上传、写shell)

    注入:之所以鸡肋就是该漏洞利用安装文件 重新生成 配置文件 写入可执行代码 鸡肋1: 具有破坏性 动作非常大 重新写了配置文件 数据库连接文件鸡肋2: 有一定安全常识的站长都会删掉 install 目 ...