this指向问题

this问题

this的四种绑定

PS:this指向在调用的时候确定 !!!!!!!!!!!!!!!!!!!!!!!!!important

1.默认绑定规则

console.log(this === window); //true
    console.log({} === {}); //false
    // 函数的独立调用
        function test(){
            console.log(this === window);
        }
        window.test() // true

不加前缀的调用均为独立调用,独立调用this指向全局

2.隐式绑定规则

PS:谁调用就指向谁

var obj = {
        a:2,
        foo:function(){
            console.log(this); // obj
            function test(){
                console.log(this); 
            }
            test() // window
            return test
        }
    }
    obj.foo()
     // 闭包指向
    obj.foo()() //window 等价于var n = obj.foo()   n()
    function man(){
        console.log(this);
    }
    var o = {
        foo:man
    }
    var b = o.foo
    function women(fn){
        fn()
    }
    women(o.foo) //window

​ 结合默认绑定规则,直接找调用者!!!!!

3.显式绑定

var obj = {
        a:2
    }
    function test(a,b,c){
        console.log(this);
        console.log(a,b,c);
    }
    // test.call(obj)   // {a: 2}
    // test.apply(obj)    // {a: 2}
    // test.bind(obj)()    // {a: 2}
    // call apply bind 传递参数
    test.call(obj,1,2,3)   
    test.apply(obj,[1,2,3])    
    test.bind(obj)(1,2,3)
	var arr = [1,2,3,4,5]
    arr.forEach(function(item,index,arr){
        console.log(this);
    },obj)

​ call apply bind 改变函数的this指向,数组,定时器等方法可以传递第二个参数指定内部的this指向(父函数可以指定子函数的this指向) 注意:只有将回调函数写成function(){}能生效 , this默认向外找一层脱离父函数

4.new 绑定

function person(){
        this.name = "zhangsan"
        console.log(this); //person {name: 'zhangsan'}
        // return {}   // p = {}
        return this // person
    }
    var p = new person()

​ new一个实例后 this指向实例对象 但是在构造函数内可以通过return 改变 p 的内容 this依旧指向person实例对象

5.this 指向优先级

​ 4>3>2>1

6.经典面试题

<script>
    function Foo(){
        getName = function(){
            console.log(1);
        }
        return this
    }
    Foo.getName = function(){console.log(2);}
    Foo.prototype.getName = function(){console.log(3);}
    var getName = function(){console.log(4);}
    function getName(){console.log(5);}

    // 请写出以下输出结果
    Foo.getName(); //2
    getName(); // 4  函数声明提升,表达式覆盖函数
    Foo().getName(); //1
    getName(); //1

    new Foo.getName() // 2 
    new Foo().getName();//3<==>var obj = new Foo();obj.getName();obj为Foo的实例对象原型链查找
    new new Foo().getName() // 3 Foo()实例对象的getName对象<==>Foo.getName {}
</script>
posted @ 2022-02-01 17:53  前端销纸  阅读(24)  评论(0编辑  收藏  举报