每個執行環境有自已的this
與使用方法環境有關係
函式使用方式 :
物件方法、簡易呼叫 (callback fun)、bind apply call(*綁定特定的this)
strict mode 嚴格模式
*********************************************************************************************
物件方法 : this 與函式宣告無關連,與使用方法有關係、物件方法調用,關注在那物件下使用
obj.fu(); fu函式會主動往前找 obj 的this
var name = 'test';
function callName() {
console.log(this.name);
}
var family = {
name : 'local',
callName : callName //往上找預解的函式
}
family.callName();
~~~~~~~~~~~~~~~~~~~~~~
與使用方法環境有關係
var test = family.callName;
test(); //show test,而不是family裡的local,因為在執行環境時,在全域環境下執行,所以取的為全域的變數
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
簡易呼叫
var a = 'window';
function test1 () {
console.log(this.a); //show window
}
test1(); //簡易呼叫
function test2(callback) {
var a = 'test';
return callback();
}
test2(function () { //此處的callback fun也為簡易呼叫
console.log(this.a + 'test'); //此處的this,若因作用域來看的話,會找test2的a,但實際為全域的a,顯示windowtest
});
var family = {
name : 'family',
callName = function() {
setTimeout(function(){ //此處fun為callback,所以this會指到全域
console.log(this.name);
}, 1000);
}
}
family.callName();
怎麼指定至family的物件下變數?
var family = {
name : 'family',
callName = function() {
var self = this; //將object的this,指定為另個變數,透過變數傳入至callback fun
setTimeout(function(){ //此處fun為callback
console.log(self.name);
}, 1000);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
apply、call、bind
var person = {
name : 'p',
}
function test(p1,p2) {
console.log(this,p1,p2); //this為全域
}
test(1,2); //一般寫法
test.call(person, 1, 2); //call方式 立刻執行,透過傳入this(person)物件,變數傳入為單個
test.apply(person, [3, 4]); //apply方式 立刻執行,透過傳入this(person)物件,變數傳入為陣列
var fn2 = test.bind(person, 5, 6); //bind方式 無法立刻執行,需成物件方式使用
fn2(5,6); //注意,此看來為簡易呼叫,但上一行先bind了this,所以不會像簡易方式去找全域
Advance 觀念 ~~~~~~~~~~~~~~~~~~~~~~~~~~
function test(p1,p2) {
console.log(this,typeof(this), p1,p2); //this為全域
}
test.call(1,2,4); // show Number , object, 2, 4
test.call(undefined,5,6); //show window全域, object, 5, 6
呼叫fun
時提供的this
值。 注意,它可能是一個無法在函數內看到的值:若這個函數是在非嚴苛模式( non-strict mode ), null
、undefined
將會被置換成全域變數,而原生型態的值將會被封裝
ref : https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/call
~~~~~~~~~~~~~~~~~~~
* strict mode 嚴格模式
在程式內執行語法檢查
(function () {
'use strict'; //定義函式為嚴格模式
a = 123; //show a is not defined
})();
function test(p1,p2) {
'use strict'; //定義函式為嚴格模式
console.log(this,typeof(this), p1,p2); //this為全域
}
test.call(undefined,5,6); //show undefined, undefined, 5, 6 //與非嚴格模式不同
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
new、DOM事件處理器、箭頭函式ES6