[JavaScript-10]this指向

1. 默认绑定

// 全局环境指向window
console.log(this);
// 函数独立调用,函数内部this指向window
function fn()
{
    console.log(this);
}
fn();

// 函数当做对象方法来调用,this指向对象
var x = 666;
var obj = 
{
    a:2,
    foo:function ()
    {
        console.log(this);
        var that = this;
        function test()
        {
            // 被嵌套的函数独立调用,this指向window
            console.log(this);
            console.log('x:',this.x);
            // console.log('x:',x); // let这么写
            console.log(that.a);
        }
        test();
    }
}
obj.foo()


2. IIFE自调用函数

// 函数当做对象方法来调用,this指向对象
var x = 666;
var obj = 
{
    a:2,
    foo:function ()
    {
        console.log(this);
        var that = this;
        function test()
        {
            // 被嵌套的函数独立调用,this指向window
            console.log(this);
            console.log('x:',this.x);
            // console.log('x:',x); // let这么写
            console.log(that.a);
        }
        test();
    }
}
obj.foo()

// IIFE自调用函数
var aa =10;
function fooo()
{
    console.log(this);
    (function test(that) // that 获取 this值 obj1
        {
            // 自调用指向window
            console.log(this);
            console.log(this.aa);
            console.log(that.a);
        }
    )(this); // 自调用传参this obj1
}
var obj1 =
{
    a       :2,
    foooo   :fooo // 函数赋值给foooo
}
obj1.foooo();

3. 隐式绑定

// 当函数当做obj对象的方法来调用,this指向当前的obj
function foo()
{
    console.log(this.a);
}
var obj = 
{
    a   :   1,
    foo :   foo,
    obj2:
    {
        a   :   2,
        foo :   foo
    }
}
// foo()直接指向obj
obj.foo();
// foo()直接指向obj2 
obj.obj2.foo();

4. 隐式丢失

4.1 赋值丢失

// 隐式丢失
// 当函数内的方法被赋值给一个变量的时候,则出现隐式丢失
var a = 0;
function foo()
{
    console.log(this.a);
}
var obj = 
{
    a   :   1,
    foo :   foo,
}
var bar = obj.foo;
// 把obj.foo()赋值给别名bar,造成隐式丢失
bar(); //0

4.2 传参丢失

// 当函数内方法被当做参数传递后,会出现隐式丢失
var b = 0;
function fooo()
{
    console.log(this.b);
}
// 传进来的fn是一个函数
function barr(fn)
{
    fn();
}
var obj1 =
{
    b:1,
    fooo:fooo
}
// 把obj1.fooo当做参数传递到barr(fn)就是赋值给fn
barr(obj1.fooo) //0

4.3 内置函数调用

// setTimeout() 载入一次执行后,延时一定时间后,再执行一次表达式;被动触发
// setInterval() 载入后立即进入计算状态,每隔指定时间救赎执行一次表达式;主动触发
setTimeout(
    function()
    {
        console.log(this);
    },
    1000
);

var a = 10;
function foo()
{
    console.log(this.a);
}
var obj =
{
    a:1,
    foo:foo
}
setTimeout(obj.foo,1000) //10

4.4 间接调用

// 间接调用
var a =2;
function foo()
{
    console.log(this.a);
}
var obj =
{
    a:3,
    foo:foo
}
var p =
{
    a:4,
    b:5
};
obj.foo(); //3
// 函数立即调用,内部this指向window
// p对象 添加新的方法
(p.foo = obj.foo)() //2
p.foo = obj.foo;
p.foo(); //4 

5. 显示绑定

// 显示绑定
// call() apply() bind()
var a = 0;
function foo()
{
    console.log(this.a);
}
var obj =
{
    a:2
}
var obj2 =
{
    a:222
}
foo() //0
// 给一个对象
foo.call(obj2) // 222
// 给一个对象或组
foo.apply(obj) // 2
var fn = foo.bind(obj2)
fn(); // 222


// 硬绑定函数套用
var a = 0;
function foo()
{
    console.log(this.a);
}
var obj =
{
    a:2
}
var bar = function()
{
    foo.call(obj)
}
bar() //2
setTimeout(bar,1) //2
bar.call(window) //2
var cc = bar.bind(window);
cc(); //2

// forEach
/*
forEach方法中的function回调有三个参数:
第一个参数是遍历的当前元素(必需),
第二个参数是当前元素的索引值(可选),
第三个参数是当前元素所属的数组对象(可选)
*/
var id = 'wind';
function fn(el, i, x) 
{
    console.log(el, i, x, this.id);
}
var obj = { id : 'fn'};
var arr = [6,66,666];
arr.forEach(fn) // wind
arr.forEach(fn,obj) // fn

6. new绑定

// new绑定
// 相当于构造函数
function fn()
{
    console.log(this);
}
var fnn = fn(); //window
fnn; 
var fnnnn = new fn(); //fn {}
var cc = fnnnn;

// new关键字来执行函数
// this指向实例化对象
function fn2()
{
    console.log(this);
    return { name : 'xxx' }
}
var fnn2 = new fn2(); //fn2 {}
fnn2;
console.log(fnn2); // { name : 'xxx' }

// new绑定3
var person =
{
    fav : function ()
    {
        console.log('thisss:',this);
        return this
    }
}
var p = new person.fav(); // fav {}
console.log(p,p === person); // fav {} false
console.log(p.constructor === person.fav); //true

7. 严格模式

// 严格模式默认指向undefined
function foo()
{
    'use strict'
    console.log(this);
}
foo(); // undefined

// apply() call() 内部的this始终是他们的第一个函数
var color = 'red';
function showcolor()
{
    'use strict'
    console.log(this);
}
showcolor.call(null); // null
showcolor.apply(undefined); // undefined
showcolor.call(window); // window

7. 箭头函数

// 箭头函数this
// 箭头函数没有自己作用域的this
// 箭头函数是在定义函数的时候绑定的
let obj = 
{
    a:222,
    fn:function()
    {
        setTimeout(function(){console.log(this);})
        // window
    }
}
obj.fn(); // Window

let obj2 =
{
    a:222,
    fn:function()
    {
        setTimeout(()=>{console.log(this)});
    }
}
obj2.fn(); // {a: 222, fn: ƒ}

posted @ 2022-11-11 12:58  LeoShi2020  阅读(24)  评论(0)    收藏  举报