摘要:一概述是一種面向對象的語言。除了基本數據類型,其他的都是對象。表示創建一個沒有原型的空對象。模擬操作符注意返回值訪問對象屬性訪問方式也就是。對象在作為值時,是作為引用傳遞的。假如判斷對象是否為數組目前的很多庫,中都是這樣實現的。
一、概述
JS是一種面向對象的語言。除了基本數據類型number, string, boolean(true, false), null, undefined,其他的都是對象。對象就是一個"name-value"對集合。
二、操作對象 2.1 創建對象JS有三種創建對象的方式:字面量,Object.create,new構造方式。
2.1.1 Object.create(null | object)嚴格來說調用Object.create方法是創建JS對象的唯一方式(其他兩種方式內部實現都是基于該方法的)。該方法功能是創建一個對象,并且該對象的原型指向create的參數對象。
參數:必須是null或者對象,否則報錯。null表示創建一個沒有原型的空對象。
var p = { a: 1}; // 對象字面量 var c1 = Object.create(p); // 對象c1的原型指向p var c2 = Object.create(null);// 對象c2沒有原型2.1.2 對象字面量
對象字面量是一種創建對象的便捷方式,見上例。其中對象p的創建方式就是對象字面量。JS解釋器會對它進行處理的,等價于:
var p = Object.create(Object.prototype); p.a = 1;
所以說對象字面量內部也是通過Object.create方式創建對象的,并且所有對象字面量方式創建的對象的原型都執行Object.prototype(如上圖)。
思考:JS解釋器如何區分語句塊花括號{}和空對象花括號{}的?
先看看這兩條語句執行的結果?
{} + [] // 0 [] + {} // "[object Object]"
當{}作為右值(賦值表達式右側),實參,在運算符的右側,被括號()包裹則作為對象,其他則視為語句塊:
下面輸出都是:"[object Object]"
console.log({} + []) // 作為實參了 ({}) + [] // 被括號包裹 var a = {} + [] //作為右值 console.log(a)
我們知道當ES6箭頭函數的函數體只有一條語句時可以省略語句塊花括號,但是如果箭頭函數返回的是一個對象該如何書寫呢?
var func1 = () => {age: 12} // 本意是想返回對象{age:12},顯然這樣寫就不對了,花括號會被作為語句塊解析 var func2 = () => ({age: 12}) // 可以用括號包裹下 var func3 = () => { return {age: 12}} // 或顯示的寫全2.1.3 new構造方式
JS的作者為了討好類語言的開發者,引入了第三者創建對象方式,即new構造方式。這使得JS對象的創建有點像類語言的對象創建。
new關鍵字 + 空格 + 函數名字 + [(參數)]
其中參數是可選的,當沒有參數傳遞時,可以省略括號。如:
function Func(){} var c1 = new Func(); var c2 = new Func; // 如果沒有參數傳遞,可以省略括號。
function Func(name){ this.name = name; } Func.prototype.say = function(){ }; var c = new Func("q");
這種方式的內部也是通過Object.create方式構建的。new方式創建對象大致分為三步:
Step1:創建一個對象A,并且對象A的原型指向構造函數的prototype屬性
Step2:以對象A綁定到構造函數上調用構造函數
Step3:如果構造函數返回值不是個非null的對象,則返回構造函數的返回值作為new表達式的值,否則以對象A作為new表達式的值。
function Func(name){ this.name = name; } Func.prototype.say = function(){ }; function create(){ // 模擬new操作符 var func = arguments[0]; var args = Array.prototype.slice.call(arguments, 1); var other = Object.create(func.prototype); // Step 1 var result = func.apply(other, args); // Step 2 return typeof result === "object" && result ? result: other; // Step3 注意返回值 } var c = create(Func, "q");2.2 訪問對象屬性
訪問方式也就是get/set/delete。在get訪問中會涉及原型鏈,set/delete訪問不會。
var Obj = { name: "john" }; // Get操作 var n = Obj.name; // 等價var n = Obj["name"]; // Set操作 Obj.age = 12;2.2.1 Get操作流程: 2.2.2 Set操作流程: 2.2.3 delete操作
可以通過delete操作符刪除對象的屬性,只能刪除對象本身的屬性。
var p = { age: 26 } var obj = Object.create(p); obj.name = "john"; console.log(obj.name); // john console.log(obj.age); // 26 delete obj.name; // 刪除屬性 delete obj.age; // 刪除屬性 console.log(obj.name); // undefined console.log(obj.age); // undefined2.3 引用對象
JS中對象是引用類型的。對象在作為值時,是作為引用傳遞的。
var a={}, b={}; // a,b分別指向不同的對象 var c = d = {}; // c,d指向同一個對象三、反射
確定對象的類型有時很有必要。
3.1 typeof 操作符通過typeof操作符可以獲取值的類型:
console.log(typeof 1); // number console.log(typeof ""); // string console.log(typeof null); // object console.log(typeof undefined); // undefined console.log(typeof true); // boolean console.log(typeof {}); // object console.log(typeof []); // object console.log(typeof function(){}); // function
但是發現這種方式中null, 數組也都是返回“object”。原因是JS中沒有原生數組類型,數組是通過對象模擬的,所以數組也是對象。但是如何區分數組和對象呢???
3.2 Object.prototype.toStringtypeof是有缺陷的,在實際應用中常通過Object.prototype.toString方法確定對象類型的。
console.log(Object.prototype.toString.call(1)); // [object Number] console.log(Object.prototype.toString.call("")); // [object String] console.log(Object.prototype.toString.call(null)); // [object Null] console.log(Object.prototype.toString.call(undefined)); // [object Undefined] console.log(Object.prototype.toString.call(true)); // [object Boolean] console.log(Object.prototype.toString.call( {})); // [object Object] console.log(Object.prototype.toString.call([])); // [object Array] console.log(Object.prototype.toString.call(function(){})); // [object Function]
看例子中輸出結果中發現不同之處了吧。假如判斷對象是否為數組:
var isArray = function(val){ return Object.prototype.toString.call(val) === "[object Array]"; }
目前的很多庫zeptojs,underscorejs中都是這樣實現的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83788.html
摘要:平時在復習基礎知識時,經常會遇到數據類型基礎數據類型內置對象包裝類型對象,檢測數據類型時,用到的值,感覺都差不多,但是又有差異。值與數據類型關系對比下圖,即可知值相較于基礎數據類型少多 平時在復習JS基礎知識時,經常會遇到JS數據類型、基礎數據類型、內置對象、包裝類型對象,檢測數據類型時,用到的typeof值,感覺都差不多,但是又有差異。今天特地整理下,方便理解。 JS數據類型 基礎數...
摘要:概述的解釋器優化器代碼可能在字節碼或者優化后的機器碼狀態下執行,而生成字節碼速度很快,而生成機器碼就要慢一些了。比如有一個函數,從獲取值引擎生成的字節碼結構是這樣的指令是獲取參數指向的對象,并存儲在,第二步則返回。 1 引言 本期精讀的文章是:JS 引擎基礎之 Shapes and Inline Caches 一起了解下 JS 引擎是如何運作的吧! JS 的運作機制可以分為 AST 分...
摘要:給普通的操作指定回調函數對象的最大優點,就是它把這一套回調函數接口,從操作擴展到了所有操作。方法用于指定對象狀態為已失敗時的回調函數。執行完畢執行成功執行失敗接收一個或多個對象作為參數,為其指定回調函數。 什么是deferred對象 開發網站的過程中,我們經常遇到某些耗時很長的javascript操作。其中,既有異步的操作(比如ajax讀取服務器數據),也有同步的操作(比如遍歷一個大型...
摘要:執行上下文作用域鏈和內部機制一執行上下文執行上下文是代碼的執行環境,它包括的值變量對象和函數。創建作用域鏈一旦可變對象創建完,引擎就開始初始化作用域鏈。 執行上下文、作用域鏈和JS內部機制(Execution context, Scope chain and JavaScript internals) 一、執行上下文 執行上下文(Execution context EC)是js代碼的執...
閱讀 1291·2021-09-22 15:00
閱讀 3309·2019-08-30 14:00
閱讀 1220·2019-08-29 17:27
閱讀 1220·2019-08-29 16:35
閱讀 689·2019-08-29 16:14
閱讀 2042·2019-08-26 13:43
閱讀 2117·2019-08-26 11:35
閱讀 2309·2019-08-23 15:34