Last active
September 21, 2015 09:15
-
-
Save kenyonduan/87d785da835bf5345465 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//this | |
//1、this 是调用当前可执行代码的对象的引用 | |
//2、this 是与 Scope 有关系的一个特殊对象。 | |
//3、JavaScript 引擎会自动初始化、更新、维持 this,且无法手动修改 this 的值(直接用就可以)。 | |
//4、PS: this 的值就是我们所说的 Context(上下文) | |
this //=> window | |
window.name = "window" // 等价于在 global 中直接定义变量 var name = 'window' | |
function getName(){ | |
return this.name; | |
}; | |
getName(); //=> 'window' | |
var obj = {name: 'object', getName: getName} | |
obj.getName(); //=> 'object' | |
//this 一般在这几种情况下会被 Javascript 引擎更新 | |
//1、初始化 global scope 的时候(默认),这个时候 this 的值被设置为 global context 或者 window 对象(浏览器中) | |
//2、进入 function 代码 | |
//这个时候 this 通常是取决于一个函数如何被调用,当函数作为对象的方法被调用时,this 会被自动设置为调用该方法的对象 | |
var object = { | |
foo: function(){ | |
alert(this === object); | |
} | |
}; | |
object.foo(); // true | |
//而当通过 new 操作符创建实例来调用一个函数时,this 的值就是新创建的对象 | |
function Foo(){ | |
return this; | |
} | |
Foo() // window(直接调用未绑定函数时,this 的值被设置为 global context 或者 window 对象(浏览器中)) | |
new Foo() // Foo | |
//this 与 Scope(execution context) 的关系 | |
//首先看以下变量的作用域: https://docs.google.com/document/d/1rixbOVvwgS89IWgdh5Bo6sbzAa1ceM6wQQ4ccYUmbuI/edit#heading=h.t6jmiuv48br9 | |
//为什么会这样呢?(Scope Chain) | |
//Scope到底是什么?: (图片: http://dmitrysoshnikov.com/wp-content/uploads/execution-context.png)这三个共同组成了 Scope: | |
//(a)、Variable Object(可以访问的变量、对象、function) | |
//(b)、Scope Chain(作用域链) | |
//浏览器执行 javascript 的规则(动图: http://davidshariff.com/blog/wp-content/uploads/2012/06/es1.gif): | |
//1、单线程(同一时间只能干一件事情) | |
//2、javascript 引擎开始执行代码时,会创建一个默认的全局 Scope | |
//3、每次调用一个 function 会创建一个新的 Scope | |
//4、每次新创建的 Scope 会被添加到调用栈栈的最顶端,浏览器总是都是运行在最顶端的 Scope。 | |
//5、执行完成后,该 Scope 被从执行栈中移除 | |
//6、将控制权归还给之前的 Scope | |
function first(){ | |
second(); | |
function second(){ | |
third(); | |
function third(){ | |
fourth(); | |
function fourth(){ | |
alert('fourth') | |
} | |
} | |
} | |
} | |
//当执行到 fourth 函数时,Scope chain 为: fourth, third, second, first, global | |
//根据变量的作用域 fourth 在查找变量是会首先从自己的变量对象开始,然后沿着 Scope chain 一直向上,找到了就返回,未找到就返回 undefined | |
//这里有几张图挺形象的: http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/ | |
//(c)、this | |
//浏览器里有哪些 Scope?(图片: http://davidshariff.com/blog/wp-content/uploads/2012/06/img1.jpg) | |
//如何手动指定 this(在执行代码的时候) ? | |
function print(test) { | |
alert(this.value + '_' + test); | |
} | |
var foo = { | |
value: 10, | |
print: print | |
}; | |
//调用 print | |
foo.print('a') //(this => foo) | |
//OR | |
foo['print']('a') //(this => foo) | |
//直接调用的 print | |
print('a') //this => global, 没有 value 属性 所以 this.value 返回 undefined | |
print.call(foo, 'a') //(this => foo) | |
//OR | |
print.apply(foo, ['a']) //(this => foo) | |
//call 和 apply 区别: | |
// 1、参数区别(call 除了第一个后面的都将作为调用方法的参数,而 apply 只接收一个数组参数) | |
// 2、性能(call 在参数小于等于 3 的时候性能超过很多,参数大于三个的时候性能不如 apply) 详见: http://segmentfault.com/q/1010000003494514 | |
//call 和 apply 都改变了 this 对象 | |
//bind 来绑定 this | |
var binding = print.bind(foo) | |
binding('a') //this => foo 当然 print.bind(foo)('a') 也是可以的 | |
var bar = { | |
value: 20, | |
print: print | |
} | |
binding.call(bar, 'a') //this => foo | |
binding.apply(bar, ['a']) //this => foo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment