Js This

  • 34
  • 0
  • Js
  • 2020-01-13

每個執行環境有自已的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 //與非嚴格模式不同

ref : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

new、DOM事件處理器、箭頭函式ES6