Object, Scope, this
Scope (變數存活的地方)
有三種. Global, Local (Function裡), Closure.
而Global全域變數其實就是全域物件(唯一)的屬性。瀏覽器:window物件、node.js:GLOBAL物件.
可開Chrome Dev tool 看變數的種類.
Scope 對於變數的存取限制
在任何語言裡, 不同scope裡的變數若有名字一樣,則是以當前scope的最小scope裡的變數來使用. 外面層無法access到裡面的scope. 此事對於內部function的宣告以一樣.
反過來說, 在任何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
Functional Scope (即Local scope) 的注意事項-1
JavaScript Object的建立
有以下3方法, 參考http://www.w3schools.com/js/js_object_definition.asp
Object Literal Notation.
較難重複製造並使用建立的屬性, 常用來用在屬性欄位不固定的case.
使用自定Function來自建物件類型(type, 有自己的名字). 使用
new
keyword.接著使用
var car1 = new Car();
方便重複使用. 較為接近一般語言裡的物件化的方法.這方法較少用, 較難重複製造並使用建立的屬性.
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, 摘要
有一句話可以形容
this
:Javascript裡的this看的是究竟是誰調用該函式它裡面提到的當是在Node.js情況下, 故輸出應為
undefined
應改為{}
, 進一步的解說是:
Node.js 一般使用時 (node index.js),檔案的最外層並不是global scope(意指會利用function將code整個包起來執行). 在最外層下一開始this={}
, 要access global要用global
這個關鍵字當做keyword來存取global物件,但一進去任何function裡,它的this就會變成指到global了。
this的重點:
this
是指到現在這位置的(物件)owner. Local scope下都有個this
來指向某物件.當產生物件時, 即
new
or.
or 'var car ={}', 在進去其functions時,this
會切換成物件的參考reference.當直接呼叫function時(沒有使用. or new or ={} or bin/call/apply時),
this
都是指向global scope的唯一物件(browser:window, node.js:global)術語
context
就是等於 this指到/參考到的物件
Scope, this 的例子-1 (變數宣告的各種case)
一般在browser上執行時. 變數的分類有
成為object的property
local變數 (如果是在browser最上層就變成打
var x=3
則會自動變成global object的property)
使用上除了直接指定為object的property外, e.g. obj.x=3
, 有其他幾種宣告方式
var x = 3;
.x = 3;//前面沒有打var/let/const
, 在Local scope這樣使用時, 若已有同樣名字的當然就是直接使用其Local變數. 若沒有, 則會變成global物件的屬性(宣告直接使用).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