this在js中有4中基本的绑定规则
1.默认绑定规则:指在全局中默认指向window
//在这是在全局当中this指向win所以相对
console.log(this===window)//true
//在函数中this指向win的这种情况,叫着——函数的独立调用。相当于window.test()
function test(){
console.log(this===window);
}
test();
//函数立即执行 ——函数声明之后立即执行.。只要函数立即执行就指向window(注意:在不同的执行环境中会有不一样)
(function(){
console.log(this);
})();
function test(){
console.log(this===window);
}
test();
2.隐式绑定规则:当通过对象的属性的方式来调用这个方法的时候就指向obj,通常称为——谁调用就指向谁
//父函数是由能力改变子函数的this的指向的
*this指在函数执行的时候才会存在,函数 不调用this就没有意义,所以每个函数产生的this可能指向相同,但是本身是不相等的。每个this指向是否相等,由当前执行方式决定
//obj.foo()通过obj点属性的方式来执行,就是谁调用就指向谁,所以指向obj。在foo执行时又创建了一个test函数,这个test函数中this的指向,就看当前的调用方式test(),典型的函数独立调用,所以就指向window
var a = 0;
var obj = {
a:2;
foo:function(){
console.log(this);//指向obj
function test(){
console.log(this);//window
}
test();
}
}
obj.foo();
*这里产生了以个闭包,当函数执行的的时候,导致函数被定义,并抛出就会形成闭包,是个现象
//这里当obj.foo();执行之后返回test,所以obj.foo()(),等价于test();这个就是典型的独立调用了,所以指向wind
var a = 0;
var obj = {
a:2;
foo:function(){
console.log(this);//指向obj
function test(){
console.log(this);//window
}
return test;
}
}
obj.foo()();
//这里如果是obj.foo()那就很经典,谁调用指向谁,obj.foo就相当于foo,所以bar就当当于foo,我们说this指向只有当函数指向的时候才会参数,所有bar(),这是才产生,这就是典型的独立调用,所以这里的this指win·
//变量赋值
var a = 0;
function foo(){
console.log(this);
}
var obj = {
a:2,
foo:foo
}
var bar = obj.foo;
bar();
//同样的例题,看函数是怎么样执行的。obj.foo等价于foo这个函数体bar(foo),foo当参数赋给bar(fn)所以就相当于foo();,这就是的典型的独立调用哈。指向window
//参数赋值
var a = 0;
function foo(){
console.log(this);
}
var bar(fn){
fn();
}
var obj = {
a:2;
foo:foo
}
//在预编译的过程中,实参赋值为形参(值的拷贝的过程,浅拷贝)
bar(obj.foo);
3.显示绑定:call,apply,bind直接改变函数的指向,这三个只是传参数的方式不一样
var a = 0;
function foo(){
console.log(this);
}
var obj = {
a:2,
foo:foo
}
var bar = obj.foo;
obj.foo();
bar.call(obj);
bar.apply(obj);
bar.bind(obj)();
4.new绑定 优先级别最高
function Person(){
var this = {};
this.a = 1;
return this;
}
var person = new Person();
#绑定的优先级,当有两种绑定方式纯在,高的优先
//这里用隐式绑定的方式输出就2,3,通过显示绑定的结果就是3,2,说明显示绑定的优先级大于隐式绑定
function foo(){
console.log(this.a);
}
var obj1 = {
a:2;
foo:foo
}
var obj2 = {
a:3
foo:foo
}
obj1.foo()
obj2.foo()
obj1.foo.call(obj2);
obj2.foo.call(obj1)
//第一个相当于在obj1上赋值了一个属性this.a,赋值完成就是2.第二个new执行能更改当前的指向指向baz,和刚才的obj1没有关系了,原本的this.a没有被删除,所有还是2,指向原来的obj1的时候才会覆盖吊原来的a,new之后又添加了一个3互不影响,所有第三个为3
function foo(b){
this.a = b;
}
var obj1 = {};
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a)//
var baz = new bar(3);
console.log(obj1.a);//
console.log(baz.a);//