Skip to content

Instantly share code, notes, and snippets.

@kenyonduan
Last active September 21, 2015 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenyonduan/87d785da835bf5345465 to your computer and use it in GitHub Desktop.
Save kenyonduan/87d785da835bf5345465 to your computer and use it in GitHub Desktop.
//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