别催了~ 正在从服务器偷取页面 . . .

javascript之this


this指向问题

this是在运行是绑定的,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

默认绑定(this指向全局对象window)

function f(){
console.log(this.a);
}
var a=2;
f();//2

在以上代码中,f()是不带任何修饰的函数引用进行调用的,所以是属于默认绑定

隐式绑定

function f(){
  console.log(this.a);
}

var obj={
  a:2,
  f:f   
}

obj.f()//2

这种情况是函数的引用有上下文对象的(obj对象的上下文),所以隐式绑定规则会把函数调用中的this绑定到这个上下文对象

function f(){
  console.log(this.a);
}

var obj={
  a:22,
  f:f
}

var obj1={
  a:2,
 obj:obj
}

obj1.obj.f();//22

引用的是最接近的变量a

注意,将如上要调用的函数赋值给另外变量后,”隐式“会消失
以下3个例子都属于赋值操作,setTimeout()函数实现也是类似的
例一:

function f(){
console.log(this.a);
}

var obj={
   a:22,
   f:f
}

var other=obj.f;
var a=123

other();//123

例二:

function f(){
console.log(this.a);
}

function fun(func){
   func();
}

var obj={
  a:22,
  f:f
}

var a=123
fun(f);//123

相当于将f赋值给func

例三:

function f(){
 console.log(this.a);
}

var obj={
  a:22,
  f:f
}

var a=123
setTimeout(obj.f,100);//123

显式绑定

指定某个对象为函数调用时的this,call、apply、bind函数

call

function f(){
  console.log(this.a);
}

var obj={
  a:22
}

var other=function(){
  f.call(obj)
}

other();//22
setTimeout(other,100);//22

apply

function f(b){
console.log(this.a,b);
return this.a+b;
}

var obj={
  a:22
}

var other=function(){
return f.apply(obj,argumments)//argumments是固定变量,不能改名
}

var res=other(3);//22 3
console.log(res);//25

bind

function f(b){
 console.log(this.a,b);
  return this.a+b;
}

function bind(f,obj){
 return function(){
    return f.apply(obj,arguments)
}

}

var obj={
  a:22
}

var other=bind(f,obj)
var res=other(3);//22 3
console.log(res);//25

new绑定

所有函数都可以用new来调用,new调用的过程见下文  使用new操作符创建构造函数的实例整个过程?

function f(a){
   this.a=a;
}

var other=new f(2);
console.log(other.a);//2

注意

  1. this四条规则的优先级就不一一细说,new绑定>显式绑定>隐式绑定>默认绑定(可参考《你不知道的javaScript上》91~95页)
  2. 当call、apply、bind需要忽略this绑定时,可以传入null(但是会改变this绑定,函数中如果使用this会绑定到全局对象),可以用∅。
  3. 还有一种叫软绑定的(好像很复杂。。。。《你不知道的javaScript上》98 有空再看看吧)
  4. 特殊的箭头函数,箭头函数中的this指的是其外层作用域.
    function f(a){
    return (a)=>{
     //这里面的this是f里的
     console.log(this.a);
      }
    }
    var obj1={
      a:1
    }
    var obj2={
      a:2
    }
    var other=f.call(obj1);
    other.call(obj2);//1
    

文章作者: John Doe
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 John Doe !
评论
  目录