Object, Scope, this

Scope (變數存活的地方)

  • 有三種. Global, Local (Function裡), Closure.

  • 而Global全域變數其實就是全域物件(唯一)的屬性。瀏覽器:window物件、node.js:GLOBAL物件.

  • 可開Chrome Dev tool 看變數的種類.

Scope 對於變數的存取限制

  1. 在任何語言裡, 不同scope裡的變數若有名字一樣,則是以當前scope的最小scope裡的變數來使用. 外面層無法access到裡面的scope. 此事對於內部function的宣告以一樣.

  2. 反過來說, 在任何function裡面,都可以存取其上面層的scope(function)的變數.

    In fact, in JavaScript, all functions have access to the scope "above" them.http://www.w3schools.com/js/js_function_closures.asp

var z = 15;
var y= 3;
function test1(){
  console.log(z); //15
  var y = 100;
  console.log("y:",y); //100  
  var x =5;  
  function test2(){
    var y = 0;  
  }
}
test1();
console.log(x); // exception
test2(); //exception too

Functional Scope (即Local scope) 的注意事項-1

JavaScript Object的建立

有以下3方法, 參考http://www.w3schools.com/js/js_object_definition.asp

  1. Object Literal Notation.

    較難重複製造並使用建立的屬性, 常用來用在屬性欄位不固定的case.

  2. 使用自定Function來自建物件類型(type, 有自己的名字). 使用new keyword.

    接著使用var car1 = new Car();方便重複使用. 較為接近一般語言裡的物件化的方法.

  3. 這方法較少用, 較難重複製造並使用建立的屬性.

JavaScript的Object Literal Notation

JavaScript Object用的Object Literal Notation方法可以做為module的一種方式(做為module的方式時通常會放functions在內部當做其property), 可以在某些時候export給別人用.

this (其他語言通常是在物件內部存取自己時使用this/self等keyword)

可參考別人整理的很好的 JavaScript:this用法整理: https://software.intel.com/zh-cn/blogs/2013/10/09/javascript-this, 摘要

  1. 有一句話可以形容this:Javascript裡的this看的是究竟是誰調用該函式

  2. 它裡面提到的當是在Node.js情況下, 故輸出應為undefined 應改為 {}, 進一步的解說是:

Node.js 一般使用時 (node index.js),檔案的最外層並不是global scope(意指會利用function將code整個包起來執行). 在最外層下一開始this={}, 要access global要用global這個關鍵字當做keyword來存取global物件,但一進去任何function裡,它的this就會變成指到global了。

this的重點:

  1. this是指到現在這位置的(物件)owner. Local scope下都有個this來指向某物件.

  2. 當產生物件時, 即new or . or 'var car ={}', 在進去其functions時, this會切換成物件的參考reference.

  3. 當直接呼叫function時(沒有使用. or new or ={} or bin/call/apply時),this都是指向global scope的唯一物件(browser:window, node.js:global)

  4. 術語context就是等於 this指到/參考到的物件

Scope, this 的例子-1 (變數宣告的各種case)

一般在browser上執行時. 變數的分類有

  1. 成為object的property

  2. local變數 (如果是在browser最上層就變成打var x=3則會自動變成global object的property)

使用上除了直接指定為object的property外, e.g. obj.x=3, 有其他幾種宣告方式

  1. var x = 3;.

  2. x = 3;//前面沒有打var/let/const, 在Local scope這樣使用時, 若已有同樣名字的當然就是直接使用其Local變數. 若沒有, 則會變成global物件的屬性(宣告直接使用).

  3. this.x = 3;

下面是此為function的物件化時的case.

如果上面最後是 TodoView(); 非物件時, 結果會不一樣.

Scope, this 的例子-2, callback時的bind

以下是沒有使用bind的case, 線上JS Bin的example codehttps://jsbin.com/tunamas/edit?html,js,console,output

使用bind解決此 exception: x is not defined

改成

callback時的 call, apply

bind類似的還有 call, apply, 上述某section有提到的https://software.intel.com/zh-cn/blogs/2013/10/09/javascript-this 也有提到'call','apply'. 可參考, 不過它的case 5.例子沒有清楚.

可另外參考http://dreamerslab.com/blog/tw/javascript-call-and-apply/, 這網頁裡使用 call, apply在設計callback.

callback的bind, call, apply使用時機整理

1. 不需使用的case 一種常見的是API的callback只有設計回傳值, 當然就沒有this等這些困擾

2. 設計者處理:

如果是像http://dreamerslab.com/blog/tw/javascript-call-and-apply/的, 自己設計一個object中的註冊callback function的API, 且callback function中要可以access同一object的mebmer, 實作時可用apply, call.

example (進階,可看可不看)

此 example 出現兩個callback, 一個自己實做, 一個jQuery

jQuery API case都是上述這種設計方式. https://api.jquery.com/click/, 線上code:

https://jsbin.com/tunamas/edit?html,js,console,output

3. 使用者處理:

若是像是上述bind的case, this.x的this(指的是TodoView物件)跟button不是同一物件, 則需要的是bind.即使用這callback的人自己去加.

若同時使用 call, bind, 則以bind傳進去的為主.

常見技巧:使用self. 目的是在不同的scope(function)裡存取外部的物件, 自定一個稱呼為 self 的變數.

這裡的技巧本質上是跟closure有關

在其他語言裡, 在不同function要存取不在function裡定義的物件, 通常是直接把物件當作參數傳進去. JavaScript也很常見.e.g.

但因為JavaScript裡常出現function裡面有function (nested function), 所以另一個做法是:

Last updated