this使用

this有四種情況!

  1. 當在函數調用的時候指向widow

  2. 當方法調用的時候指向調用對象

  3. 當用apply和call上下文調用的時候指向傳入的第一個參數

  4. 構造函數調用指向實例對象

函數裏的this可以分爲兩種來記憶:

如果是使用new方式創建對象,this指向新建的那個對象;

如果只是普通的調用,誰調用這個函數,函數裏的this就指向誰~

apply

可以改變this的指向,接收兩個參數,第一個參數是在其中運行函數的作用域,另外一個是參數數組

var name = "xh";
var age = 22;
function print(name, age) {
    console.log('this指向的值', this);
    console.log(this.name, this.age);
    console.log('傳過來的值', name, age);

}

let obj = {
    name: 'xm',
    age: '21',
    print: function () {
        console.log('this指向的值', this);
        console.log(this.name, this.age);
    }
};

print.apply(this, ['xd', 20]);
console.log("================");
print.apply(window, ['xd', 20]);
console.log("================");
print.apply(obj, ['xd', 20]);
console.log("================");
print.apply(obj);
console.log("================");
print.apply();
console.log("================");
obj.print.apply();

如果apply不帶任何參數,默認指向windows

call

callapply一樣,可以改變this的指向,只是參數傳遞的方式不一樣,第一個參數是在其中運行函數的作用域,其他的參數與函數的參數一一對應,和apply不一樣,apply的第二個參數是一個數組,call的參數必須一個一個的傳入進去

var name = "xh";
var age = 22;
function print(name, age) {
    console.log('this指向的值', this);
    console.log(this.name, this.age);
    console.log('傳過來的值', name, age);

}

let obj = {
    name: 'xm',
    age: '21',
    print: function () {
        console.log('this指向的值', this);
        console.log(this.name, this.age);
    }
};

print.call(this, 'xd', 20);
console.log("================");
print.call(window, 'xd', 20);
console.log("================");
print.call(obj, 'xd', 20);
console.log("================");
print.call(obj);
console.log("================");
print.call();
console.log("================");
obj.print.call();

callapply一樣,如果沒有參數,默認指向的是windows

bind

bind也可以改變函數的this指向,可以綁定this的函數的作用域

var name = "xh";
var age = 22;
function print(name, age) {
    console.log('this指向的值', this);
    console.log(this.name, this.age);
    console.log('傳過來的值', name, age);

}

let obj = {
    name: 'xm',
    age: '21',
    print: function () {
        console.log('this指向的值', this);
        console.log(this.name, this.age);
    }
};

let print1 = print.bind(window);
print1();
console.log("==============");
let print2 = print.bind(obj);
print2();
console.log("==============");
let print3 = print.bind();
print3();
console.log("==============");
let print4 = obj.print.bind();
print4();

bind在沒有參數的情況下,默認綁定的是windows

面試題

var name = "The window";
let object = {
    name: "my Object name",
    getNameFun: function () {
        return function () {
            return this.name;
        };
    }
};
console.log(object.getNameFun()());  //The window
//可拆解爲
// var result = object.getNameFun();
// result(); //等價與window.result();
//所以object裏面的this是windows
//使用var定義變量,定義的是全局變量,即var name = "The window"等價與windows.name = "The window"


let name1 = "The window 1";
let object1 = {
    name: "my Object name 1",
    getNameFun: function () {
        return function () {
            return this.name1;
        };
    }
};
console.log(object1.getNameFun()());  //undefined
//可拆解爲
// var result = object.getNameFun();
// result(); //等價與window.result();
//所以object裏面的this是windows
//使用let定義變量,定義的是局部變量,即let name = "The window 1"並不會在windows變量上添加一個name屬性
//所以輸出爲undefined


var name2 = "The window2";
let object2 = {
    name2: "my Object name 2",
    getNameFun: function () {
        let that = this;
        return function () {
            return that.name2;
        }
    }
};
console.log(object2.getNameFun()());  //my Object name 2
//可拆解爲
var result = object.getNameFun();
//result裏面有個閉包,閉包的that屬性指向object
result(); //等價與window.result();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章