最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

千鋒教育JavaScript全套視頻教程(10天學(xué)會Js,前端javascrip

2023-07-21 16:42 作者:玲兒甜妹妹  | 我要投稿

一.this對象的理解

函數(shù)的 this 關(guān)鍵字在 JavaScript 中的表現(xiàn)略有不同,此外,在嚴(yán)格模式和非嚴(yán)格模式之間也會有一些差別

在絕大多數(shù)情況下,函數(shù)的調(diào)用方式?jīng)Q定了 this 的值(運(yùn)行時(shí)綁定)

this 關(guān)鍵字是函數(shù)運(yùn)行時(shí)自動生成的一個內(nèi)部對象,只能在函數(shù)內(nèi)部使用,總指向調(diào)用它的對象

舉個例子:

function baz() {
??// 當(dāng)前調(diào)用棧是:baz
??// 因此,當(dāng)前調(diào)用位置是全局作用域
??
??console.log( "baz" );
??bar(); // <-- bar的調(diào)用位置
}

function bar() {
??// 當(dāng)前調(diào)用棧是:baz --> bar
??// 因此,當(dāng)前調(diào)用位置在baz中
??
??console.log( "bar" );
??foo(); // <-- foo的調(diào)用位置
}

function foo() {
??// 當(dāng)前調(diào)用棧是:baz --> bar --> foo
??// 因此,當(dāng)前調(diào)用位置在bar中
??
??console.log( "foo" );
}

baz(); // <-- baz的調(diào)用位置

同時(shí),this在函數(shù)執(zhí)行過程中,this一旦被確定了,就不可以再更改

var a = 10;
var obj = {
?a: 20
}

function fn() {
?this = obj; // 修改this,運(yùn)行后會報(bào)錯
?console.log(this.a);
}

fn();

二、綁定規(guī)則

根據(jù)不同的使用場合,this有不同的值,主要分為下面幾種情況:

  • 默認(rèn)綁定
  • 隱式綁定
  • new綁定
  • 顯示綁定

默認(rèn)綁定

全局環(huán)境中定義person函數(shù),內(nèi)部使用this關(guān)鍵字

var name = 'Jenny';
function person() {
??return this.name;
}
console.log(person());?//Jenny

上述代碼輸出Jenny,原因是調(diào)用函數(shù)的對象在游覽器中位window,因此this指向window,所以輸出Jenny

注意:

嚴(yán)格模式下,不能將全局對象用于默認(rèn)綁定,this會綁定到undefined,只有函數(shù)運(yùn)行在非嚴(yán)格模式下,默認(rèn)綁定才能綁定到全局對象

隱式綁定

函數(shù)還可以作為某個對象的方法調(diào)用,這時(shí)this就指這個上級對象

function test() {
?console.log(this.x);
}

var obj = {};
obj.x = 1;
obj.m = test;

obj.m(); // 1

這個函數(shù)中包含多個對象,盡管這個函數(shù)是被最外層的對象所調(diào)用,this指向的也只是它上一級的對象

var o = {
??a:10,
??b:{
????fn:function(){
??????console.log(this.a); //undefined
???}
?}
}
o.b.fn();

上述代碼中,this的上一級對象為b,b內(nèi)部并沒有a變量的定義,所以輸出undefined

這里再舉一種特殊情況

var o = {
??a:10,
??b:{
????a:12,
????fn:function(){
??????console.log(this.a); //undefined
??????console.log(this); //window
???}
?}
}
var j = o.b.fn;
j();

此時(shí)this指向的是window,這里的大家需要記住,this永遠(yuǎn)指向的是最后調(diào)用它的對象,雖然fn是對象b的方法,但是fn賦值給j時(shí)候并沒有執(zhí)行,所以最終指向window

new綁定

通過構(gòu)建函數(shù)new關(guān)鍵字生成一個實(shí)例對象,此時(shí)this指向這個實(shí)例對象

function test() {
 this.x = 1;
}

var obj = new test();
obj.x // 1

上述代碼之所以能過輸出1,是因?yàn)?code>new關(guān)鍵字改變了this的指向

這里再列舉一些特殊情況:

new過程遇到return一個對象,此時(shí)this指向?yàn)榉祷氐膶ο?/p>

function fn()?
{?
??this.user = 'xxx';?
??return {};?
}
var a = new fn();?
console.log(a.user); //undefined

如果返回一個簡單類型的時(shí)候,則this指向?qū)嵗龑ο?/p>

function fn()?
{?
??this.user = 'xxx';?
??return 1;
}
var a = new fn;?
console.log(a.user); //xxx

注意的是null雖然也是對象,但是此時(shí)new仍然指向?qū)嵗龑ο?/p>

function fn()?
{?
??this.user = 'xxx';?
??return null;
}
var a = new fn;?
console.log(a.user); //xxx

顯示修改

apply()、call()、bind()是函數(shù)的一個方法,作用是改變函數(shù)的調(diào)用對象。它的第一個參數(shù)就表示改變后的調(diào)用這個函數(shù)的對象。因此,這時(shí)this指的就是這第一個參數(shù)

var x = 0;
function test() {
 console.log(this.x);
}

var obj = {};
obj.x = 1;
obj.m = test;
obj.m.apply(obj) // 1

關(guān)于apply、call、bind三者的區(qū)別,我們后面再詳細(xì)說

三、箭頭函數(shù)

在 ES6 的語法中還提供了箭頭函語法,讓我們在代碼書寫時(shí)就能確定 this 的指向(編譯時(shí)綁定)

舉個例子:

const obj = {
?sayThis: () => {
??console.log(this);
 }
};

obj.sayThis(); // window 因?yàn)?JavaScript 沒有塊作用域,所以在定義 sayThis 的時(shí)候,里面的 this 就綁到 window 上去了
const globalSay = obj.sayThis;
globalSay(); // window 瀏覽器中的 global 對象

雖然箭頭函數(shù)的this能夠在編譯的時(shí)候就確定了this的指向,但也需要注意一些潛在的坑

下面舉個例子:

綁定事件監(jiān)聽

const button = document.getElementById('mngb');
button.addEventListener('click', ()=> {
??console.log(this === window) // true
??this.innerHTML = 'clicked button'
})

上述可以看到,我們其實(shí)是想要this為點(diǎn)擊的button,但此時(shí)this指向了window

包括在原型上添加方法時(shí)候,此時(shí)this指向window

Cat.prototype.sayName = () => {
??console.log(this === window) //true
??return this.name
}
const cat = new Cat('mm');
cat.sayName()

同樣的,箭頭函數(shù)不能作為構(gòu)建函數(shù)

四、優(yōu)先級

隱式綁定 VS 顯式綁定

function foo() {
??console.log( this.a );
}

var obj1 = {
??a: 2,
??foo: foo
};

var obj2 = {
??a: 3,
??foo: foo
};

obj1.foo(); // 2
obj2.foo(); // 3

obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2

顯然,顯示綁定的優(yōu)先級更高

new綁定 VS 隱式綁定

function foo(something) {
??this.a = something;
}

var obj1 = {
??foo: foo
};

var obj2 = {};

obj1.foo( 2 );
console.log( obj1.a ); // 2

obj1.foo.call( obj2, 3 );
console.log( obj2.a ); // 3

var bar = new obj1.foo( 4 );
console.log( obj1.a ); // 2
console.log( bar.a ); // 4

可以看到,new綁定的優(yōu)先級>隱式綁定

new綁定 VS 顯式綁定

因?yàn)?code>new和apply、call無法一起使用,但硬綁定也是顯式綁定的一種,可以替換測試

function foo(something) {
??this.a = something;
}

var obj1 = {};

var bar = foo.bind( obj1 );
bar( 2 );
console.log( obj1.a ); // 2

var baz = new bar( 3 );
console.log( obj1.a ); // 2
console.log( baz.a ); // 3

bar被綁定到obj1上,但是new bar(3) 并沒有像我們預(yù)計(jì)的那樣把obj1.a修改為3。但是,new修改了綁定調(diào)用bar()中的this

我們可認(rèn)為new綁定優(yōu)先級>顯式綁定

綜上,new綁定優(yōu)先級 > 顯示綁定優(yōu)先級 > 隱式綁定優(yōu)先級 > 默認(rèn)綁定優(yōu)先級函數(shù)的 this 關(guān)鍵字在 JavaScript 中的表現(xiàn)略有不同,此外,在嚴(yán)格模式和非嚴(yán)格模式之間也會有一些差別

在絕大多數(shù)情況下,函數(shù)的調(diào)用方式?jīng)Q定了 this 的值(運(yùn)行時(shí)綁定)

this 關(guān)鍵字是函數(shù)運(yùn)行時(shí)自動生成的一個內(nèi)部對象,只能在函數(shù)內(nèi)部使用,總指向調(diào)用它的對象

舉個例子:

function baz() {
??// 當(dāng)前調(diào)用棧是:baz
??// 因此,當(dāng)前調(diào)用位置是全局作用域
??
??console.log( "baz" );
??bar(); // <-- bar的調(diào)用位置
}

function bar() {
??// 當(dāng)前調(diào)用棧是:baz --> bar
??// 因此,當(dāng)前調(diào)用位置在baz中
??
??console.log( "bar" );
??foo(); // <-- foo的調(diào)用位置
}

function foo() {
??// 當(dāng)前調(diào)用棧是:baz --> bar --> foo
??// 因此,當(dāng)前調(diào)用位置在bar中
??
??console.log( "foo" );
}

baz(); // <-- baz的調(diào)用位置

同時(shí),this在函數(shù)執(zhí)行過程中,this一旦被確定了,就不可以再更改

var a = 10;
var obj = {
?a: 20
}

function fn() {
?this = obj; // 修改this,運(yùn)行后會報(bào)錯
?console.log(this.a);
}

fn();

二、綁定規(guī)則

根據(jù)不同的使用場合,this有不同的值,主要分為下面幾種情況:

  • 默認(rèn)綁定
  • 隱式綁定
  • new綁定
  • 顯示綁定

默認(rèn)綁定

全局環(huán)境中定義person函數(shù),內(nèi)部使用this關(guān)鍵字

var name = 'Jenny';
function person() {
??return this.name;
}
console.log(person());?//Jenny

上述代碼輸出Jenny,原因是調(diào)用函數(shù)的對象在游覽器中位window,因此this指向window,所以輸出Jenny

注意:

嚴(yán)格模式下,不能將全局對象用于默認(rèn)綁定,this會綁定到undefined,只有函數(shù)運(yùn)行在非嚴(yán)格模式下,默認(rèn)綁定才能綁定到全局對象

隱式綁定

函數(shù)還可以作為某個對象的方法調(diào)用,這時(shí)this就指這個上級對象

function test() {
?console.log(this.x);
}

var obj = {};
obj.x = 1;
obj.m = test;

obj.m(); // 1

這個函數(shù)中包含多個對象,盡管這個函數(shù)是被最外層的對象所調(diào)用,this指向的也只是它上一級的對象

var o = {
??a:10,
??b:{
????fn:function(){
??????console.log(this.a); //undefined
???}
?}
}
o.b.fn();

上述代碼中,this的上一級對象為b,b內(nèi)部并沒有a變量的定義,所以輸出undefined

這里再舉一種特殊情況

var o = {
??a:10,
??b:{
????a:12,
????fn:function(){
??????console.log(this.a); //undefined
??????console.log(this); //window
???}
?}
}
var j = o.b.fn;
j();

此時(shí)this指向的是window,這里的大家需要記住,this永遠(yuǎn)指向的是最后調(diào)用它的對象,雖然fn是對象b的方法,但是fn賦值給j時(shí)候并沒有執(zhí)行,所以最終指向window

new綁定

通過構(gòu)建函數(shù)new關(guān)鍵字生成一個實(shí)例對象,此時(shí)this指向這個實(shí)例對象

function test() {
 this.x = 1;
}

var obj = new test();
obj.x // 1

上述代碼之所以能過輸出1,是因?yàn)?code>new關(guān)鍵字改變了this的指向

這里再列舉一些特殊情況:

new過程遇到return一個對象,此時(shí)this指向?yàn)榉祷氐膶ο?/p>

function fn()?
{?
??this.user = 'xxx';?
??return {};?
}
var a = new fn();?
console.log(a.user); //undefined

如果返回一個簡單類型的時(shí)候,則this指向?qū)嵗龑ο?/p>

function fn()?
{?
??this.user = 'xxx';?
??return 1;
}
var a = new fn;?
console.log(a.user); //xxx

注意的是null雖然也是對象,但是此時(shí)new仍然指向?qū)嵗龑ο?/p>

function fn()?
{?
??this.user = 'xxx';?
??return null;
}
var a = new fn;?
console.log(a.user); //xxx

顯示修改

apply()、call()、bind()是函數(shù)的一個方法,作用是改變函數(shù)的調(diào)用對象。它的第一個參數(shù)就表示改變后的調(diào)用這個函數(shù)的對象。因此,這時(shí)this指的就是這第一個參數(shù)

var x = 0;
function test() {
 console.log(this.x);
}

var obj = {};
obj.x = 1;
obj.m = test;
obj.m.apply(obj) // 1

關(guān)于apply、call、bind三者的區(qū)別,我們后面再詳細(xì)說

三、箭頭函數(shù)

在 ES6 的語法中還提供了箭頭函語法,讓我們在代碼書寫時(shí)就能確定 this 的指向(編譯時(shí)綁定)

舉個例子:

const obj = {
?sayThis: () => {
??console.log(this);
 }
};

obj.sayThis(); // window 因?yàn)?JavaScript 沒有塊作用域,所以在定義 sayThis 的時(shí)候,里面的 this 就綁到 window 上去了
const globalSay = obj.sayThis;
globalSay(); // window 瀏覽器中的 global 對象

雖然箭頭函數(shù)的this能夠在編譯的時(shí)候就確定了this的指向,但也需要注意一些潛在的坑

下面舉個例子:

綁定事件監(jiān)聽

const button = document.getElementById('mngb');
button.addEventListener('click', ()=> {
??console.log(this === window) // true
??this.innerHTML = 'clicked button'
})

上述可以看到,我們其實(shí)是想要this為點(diǎn)擊的button,但此時(shí)this指向了window

包括在原型上添加方法時(shí)候,此時(shí)this指向window

Cat.prototype.sayName = () => {
??console.log(this === window) //true
??return this.name
}
const cat = new Cat('mm');
cat.sayName()

同樣的,箭頭函數(shù)不能作為構(gòu)建函數(shù)

四、優(yōu)先級

隱式綁定 VS 顯式綁定

function foo() {
??console.log( this.a );
}

var obj1 = {
??a: 2,
??foo: foo
};

var obj2 = {
??a: 3,
??foo: foo
};

obj1.foo(); // 2
obj2.foo(); // 3

obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2

顯然,顯示綁定的優(yōu)先級更高

new綁定 VS 隱式綁定

function foo(something) {
??this.a = something;
}

var obj1 = {
??foo: foo
};

var obj2 = {};

obj1.foo( 2 );
console.log( obj1.a ); // 2

obj1.foo.call( obj2, 3 );
console.log( obj2.a ); // 3

var bar = new obj1.foo( 4 );
console.log( obj1.a ); // 2
console.log( bar.a ); // 4

可以看到,new綁定的優(yōu)先級>隱式綁定

new綁定 VS 顯式綁定

因?yàn)?code>new和apply、call無法一起使用,但硬綁定也是顯式綁定的一種,可以替換測試

function foo(something) {
??this.a = something;
}

var obj1 = {};

var bar = foo.bind( obj1 );
bar( 2 );
console.log( obj1.a ); // 2

var baz = new bar( 3 );
console.log( obj1.a ); // 2
console.log( baz.a ); // 3

bar被綁定到obj1上,但是new bar(3) 并沒有像我們預(yù)計(jì)的那樣把obj1.a修改為3。但是,new修改了綁定調(diào)用bar()中的this

我們可認(rèn)為new綁定優(yōu)先級>顯式綁定

綜上,new綁定優(yōu)先級 > 顯示綁定優(yōu)先級 > 隱式綁定優(yōu)先級 > 默認(rèn)綁定優(yōu)先級

千鋒教育JavaScript全套視頻教程(10天學(xué)會Js,前端javascrip的評論 (共 條)

分享到微博請遵守國家法律
闻喜县| 陵川县| 彭山县| 靖远县| 旬邑县| 上高县| 宁武县| 犍为县| 依安县| 乐平市| 临沂市| 五常市| 横山县| 宝丰县| 隆德县| 文安县| 峡江县| 商水县| 东丰县| 黔西| 印江| 东海县| 乐亭县| 榆社县| 嘉鱼县| 黔江区| 蒙山县| 弥勒县| 得荣县| 乐山市| 庆阳市| 金乡县| 项城市| 德昌县| 南川市| 扶沟县| 大丰市| 姚安县| 玉环县| 宣威市| 清镇市|