標籤:undefined details 是什麼 定義 傳回值 正確答案 ase 引擎 先來
今天碰到一個題,感覺還是有一定的迷惑性的。而這也正說明一點,有時候形成的慣性思維很要命,特別是遇到小的知識點的時候。不多說,先來看看這道題:
運行這段代碼之後,“mike”的值是什嗎?
function Person(name, age){ this.name = name; this.age = parseInt(age,10); }var mike = Person(‘mike‘, ‘25‘);
A. null
B. 代碼不能運行,文法有錯誤
C. { name: ‘Mike‘, age: 25 }
D. undefined
E. { name: ‘Mike‘, age: ‘25‘ }
這道題我咋一看。毫不猶豫選了C,結果錯了。錯誤原因很明顯:誤把最後一句var mike = Person(...);當成了Person類的執行個體化。而沒有發現少了new 操作符。
那有沒有new 操作符到底意味著什麼呢?我們知道,在JavaScript中,在實現物件導向的時候,原本上是沒有“類”這一概念的,只是我們藉助C++/Java 中的OOP來理解它。
在JS中,用function 關鍵字來定義“類”,所以這裡的“類”本質上就是函數,函數就是對象。在這裡不得不說一句,那如何區分定義的到底是一個“類”還是一個普通的函數呢?通常編程習慣上
定義“類”時,類名首字母大寫,定義普通函數時就用小寫。其次,看內建函式體的行為。
本題很明顯,是在定義一個“Person”類。但別忘了,它仍然是一個函數。所以本題在最後調用的時候,不加new 操作符,就把它看成一個普通函數來調用。其實是非常簡單的一條語句。但前後的思維反差有點讓人
轉不過彎(也可能就我一個菜鳥沒有轉過彎^_^)。而回到函數上來考慮Person(),這是一個沒有傳回值的函數。我們又知道,JS的函數沒有return 語句的時候,預設返回的是 undefined。
所以。。。。。。。。。var mike = undefined.正確答案選D。
下面關於new 操作符的原文地址:http://blog.csdn.net/motian06/article/details/8258942
new 操作符
在有上面的基礎概念的介紹之後,在加上new操作符,我們就能完成傳統物件導向的class + new的方式建立對象,在JavaScript中,我們將這類方式成為Pseudoclassical。
基於上面的例子,我們執行如下代碼
var obj = new Base();
這樣代碼的結果是什麼,我們在javascript引擎中看到的物件模型是:
new操作符具體幹了什麼呢?其實很簡單,就幹了三件事情。
var obj = {};obj.__proto__ = Base.prototype;Base.call(obj);
第一行,我們建立了一個Null 物件obj
第二行,我們將這個Null 物件的__proto__成員指向了Base函數對象prototype成員對象
第三行,我們將Base函數對象的this指標替換成obj,然後再調用Base函數,於是我們就給obj對象賦值了一個id成員變數,這個成員變數的值是”base”,關於call函數的用法,請參看陳皓《Javascript 物件導向編程》文章
如果我們給Base.prototype的對象添加一些函數會有什麼效果呢?
例如代碼如下:
Base.prototype.toString = function() { return this.id;}
那麼當我們使用new建立一個新對象的時候,根據__proto__的特性,toString這個方法也可以做新對象的方法被訪問到。於是我們看到了:
構造子中,我們來設定‘類’的成員變數(例如:例子中的id),構造子物件prototype中我們來設定‘類’的公用方法。於是通過函數對象和Javascript特有的__proto__與prototype成員及new操作符,類比出類和類執行個體化的效果。
由一道小題談談JS的new操作符