摘要:使函數(shù)不同于其他對象的決定性特性是函數(shù)存在一個被稱為的內(nèi)部屬性。其中,是一個布爾值,指明改對象本身是否可以被修改值為。注意凍結(jié)對象和封印對象均要在嚴(yán)格模式下使用。
數(shù)據(jù)類型
在JavaScript中,數(shù)據(jù)類型分為兩類:
原始類型:保存一些簡單數(shù)據(jù),如true,5等。JavaScript共有5中原始類型:
boolean:布爾,值為true或false
number:數(shù)字,值為任何整型會浮點數(shù)值
string:字符串,值為由單引號或雙引號括出的單個字符或連續(xù)字符(JavaScript不區(qū)分字符類型)
null:空類型,其僅有一個值:nulll
undefined:未定義,其僅有一個值:undefined
var name = "Pomy"; var blog = "http://www.ido321.com"; var age = 22; alert(typeof blog); //"string" alert(typeof age); //"number"
原始類型的值是直接保存在變量中,并可以用typeof進(jìn)行檢測。但是typeof對null的檢測是返回object,而不是返回null:
//彈出Not null if(typeof null){ alert("Not null"); }else{ alert("null"); }
所以檢測null時,最好用全等于(===),其還能避免強制類型轉(zhuǎn)換:
console.log("21" === 21); //false console.log("21" == 21); //true console.log(undefined == null); //true console.log(undefined === null); //false
對于字符串、數(shù)字或者布爾值,其都有對應(yīng)的方法,這些方法來自于對應(yīng)的原始封裝類型:String、Number和Boolean。原始封裝類型將被自動創(chuàng)建。
var name = "Pomy"; var char = name.charAt(0); console.log(char); //"P"
在JavaScript引擎中發(fā)生的事情:
var name = "Pomy"; var temp = new String(name); var char = temp.charAt(0); temp = null; console.log(char); //"P"
字符串對象的引用在用完之后立即被銷毀,所以不能給字符串添加屬性,并且instanceof檢測對應(yīng)類型時均返回false:
var name = "Pomy"; name.age = 21; console.log(name.age); //undefined console.log(name instanceof String); //false
引用類型:保存為對象,實質(zhì)是指向內(nèi)存位置的引用,所以不在變量中保存對象。除了自定義的對象,JavaScript提供了6中內(nèi)建類型:
Array:數(shù)組類型,以數(shù)字為索引的一組值的有序列表
Date:日期和時間類型
Error:運行期錯誤類型
Function:函數(shù)類型
Object:通用對象類型
RegExp:正則表達(dá)式類型
可以用new來實例化每一個對象,或者用字面量形式來創(chuàng)建對象:
var obj = new Object; var own = { name:"Pomy", blog:"http://www.ido321.com", "my age":22 }; console.log(own.blog); //訪問屬性 console.log(own["my age"]); obj = null; //解除引用
obj 并不包含對象實例,而是一個指向內(nèi)存中實際對象所在位置的指針(或者說引用)。因為typeof對所有非函數(shù)的引用類型均返回object,所以需要用instanceof來檢測引用類型。
函數(shù)在JavaScript中,函數(shù)就是對象。使函數(shù)不同于其他對象的決定性特性是函數(shù)存在一個被稱為[[Call]]的內(nèi)部屬性。內(nèi)部屬性無法通過代碼訪問而是定義了代碼執(zhí)行時的行為。
創(chuàng)建形式1、函數(shù)聲明:用function關(guān)鍵字,會被提升至上下文
2、函數(shù)表達(dá)式:不能被提升
3、實例化Function內(nèi)建類型
sayHi(); //函數(shù)提升 function sayHi(){ console.log("Hello"); } //其他等效等效方式 /* var sayHi = function(){ console.log("Hello"); } var sayHi = new Function(" console.log("Hello");"); */參數(shù)
JavaScript函數(shù)的另外一個獨特之處在于可以給函數(shù)傳遞任意數(shù)量的參數(shù)。函數(shù)參數(shù)被保存在arguments類數(shù)組對象中,其自動存在函數(shù)中,能通過數(shù)字索引來引用參數(shù),但它不是數(shù)組實例:
alert(Array.isArray(arguments)); //false
類數(shù)組對象arguments 保存的是函數(shù)的實參,但并不會忽略形參。因而,arguments.length返回實參列表的長度,arguments.callee.length返回形參列表的長度。
function ref(value){ return value; } console.log(ref("Hi")); console.log(ref("Hi",22)); console.log(ref.length); //1函數(shù)中的this
關(guān)于this的問題,可參考此文:JavaScript中的this。
JavaScript提供了三個方法用于改變this的指向:call、apply和bind。三個函數(shù)的第一個參數(shù)都是指定this的值,其他參數(shù)均作為參數(shù)傳遞給函數(shù)。
對象是一種引用類型,創(chuàng)建對象常見的兩種方式:Object構(gòu)造函數(shù)和對象字面量形式:
var per1 = { name:"Pomy", blog:"http://www.ido321.com" }; var per2 = new Object; per2.name = "不寫代碼的碼農(nóng)";屬性操作
在JavaScript中,可以隨時為對象添加屬性:
per1.age = 0; per1.sayName = function(){ alert(this.name); //"Pomy" }
因而,在檢測對象屬性是否存在時,常犯的一個錯誤是:
//結(jié)果是false if(per1.age){ alert(true) }else{ alert(false); }
per1.age 是存在的,但是其值是0,所以不能滿足if條件。if判斷中的值是一個對象、非空字符串、非零數(shù)字或true時,判斷會評估為真;而當(dāng)值是一個null、undefined、0、false、NaN或空字符串時評估為假。
因而,檢測屬性是否存在時,有另外的兩種方式:in和hasOwnProperty(),前者會檢測原型屬性和自有(實例)屬性,后者只檢測自有(實例)屬性。
console.log("age" in per1); //true console.log(per1.hasOwnProperty("age")); //true console.log("toString" in per1); //true console.log(per1.hasOwnProperty("toString")); //false
對象per1并沒有定義toString,該屬性繼承于Object.prototype,所以in和hasOwnProperty()檢測該屬性時出現(xiàn)差異。如果只想判斷一個對象屬性是不是原型,可以利用如下方法:
function isPrototypeProperty(obj,name){ return name in obj && !obj.hasOwnProperty(name); }
若要刪除一個屬性,用delete操作符,用于刪除自有屬性,不能刪除原型屬性。
per1.toString = function(){ console.log("per1對象"); }; console.log(per1.hasOwnProperty("toString")); //true per1.toString(); //"per1對象" delete per1.toString; console.log(per1.hasOwnProperty("toString")); //false console.log(per1.toString()); //[object Object]
有時需要枚舉對象的可枚舉屬性,也有兩種方式:for-in循環(huán)和Object.keys(),前者依舊會遍歷出原型屬性,后者只返回自有屬性。所有可枚舉屬性的內(nèi)部屬性[[Enumerable]]的值均為true。
var per3 = { name:"Pomy", blog:"http://www.ido321.com", age:22, getAge:function(){ return this.age; } };
實際上,大部分原生屬性的[[Enumerable]]的值均為false,即該屬性不能枚舉。可以通過propertyIsEnumerable()檢測屬性是否可以枚舉:
console.log(per3.propertyIsEnumerable("name")); //true var pros = Object.keys(per3); //返回可枚舉屬性的名字?jǐn)?shù)組 console.log("length" in pros); //true console.log(pros.propertyIsEnumerable("length")); //false
屬性name是自定義的,可枚舉;屬性length是Array.prototype的內(nèi)建屬性,不可枚舉。
屬性類型屬性有兩種類型:數(shù)據(jù)屬性和訪問器屬性。二者均具有四個屬性特征:
數(shù)據(jù)屬性:[[Enumerable]]、[[Configurable]]、[[Value]]和[[Writable]]
訪問器屬性:[[Enumerable]]、[[Configurable]]、[[Get]]和[[Set]]
[[Enumerable]] :布爾值,屬性是否可枚舉,自定義屬性默認(rèn)是true。
[[Configurable]] :布爾值,屬性是否可配置(可修改或可刪除),自定義屬性默認(rèn)是true。它是不可逆的,即設(shè)置成false后,再設(shè)置成true會報錯。
[[Value]]:保存屬性的值。
[[Writable]]:布爾值,屬性是否可寫,所有屬性默認(rèn)可寫。
[[Get]]:獲取屬性值。
[[Set]]:設(shè)置屬性值。
ES 5提供了兩個方法用于設(shè)置這些內(nèi)部屬性:
Object.defineProperty(obj,pro,desc_map) 和 Object.defineProperties(obj,pro_map)。利用這兩個方法為per3添加一個屬性和創(chuàng)建一個新對象per4:
Object.defineProperty(per3,"sex",{ value:"male", enumerable:false, configurable:false, //屬性不能刪除和修改,該值也不能被設(shè)置成true }); console.log(per3.sex); //"male" console.log(per3.propertyIsEnumerable("sex")); //false delete per3.sex; //不能刪除 per3.sex = "female"; //不能修改 console.log(per3.sex); //"male" Object.defineProperty(per3,"sex",{ configurable:true, //報錯 }); per4 = {}; Object.defineProperties(per4,{ name:{ value:"dwqs", writable:true }, blog:{ value:"http://blog.92fenxiang.com" }, Name:{ get:function(){ return this.name; }, set:function(value){ this.name = value; }, enumerable:true, configurable:true } }); console.log(per4.name); //dwqs per4.Name = "Pomy"; console.log(per4.Name); //Pomy
需要注意的是,通過這兩種方式來定義新屬性時,如果不指定特征值,則默認(rèn)是false,也不能創(chuàng)建同時具有數(shù)據(jù)特征和訪問器特征的屬性。可以通過Object.getOwnPropertyDescriptor()方法來獲取屬性特征的描述,接受兩個參數(shù):對象和屬性名。若屬性存在,則返回屬性描述對象。
var desc = Object.getOwnPropertyDescriptor(per4,"name"); console.log(desc.enumerable); //false console.log(desc.configurable); //false console.log(desc.writable); //true
根據(jù)屬性的屬性類型,返回的屬性描述對象包含其對應(yīng)的四個屬性特征。
禁止修改對象對象和屬性一樣具有指導(dǎo)其行為的內(nèi)部特征。其中,[[Extensible]]是一個布爾值,指明改對象本身是否可以被修改([[Extensible]]值為true)。創(chuàng)建的對象默認(rèn)都是可以擴展的,可以隨時添加新的屬性。
ES5提供了三種方式:
Object.preventExtensions(obj):創(chuàng)建不可擴展的obj對象,可以利用Object.isExtensible(obj)來檢測obj是否可以擴展。嚴(yán)格模式下給不擴展對象添加屬性會報錯,非嚴(yán)格模式下則添加失敗。
Object.seal(obj):封印對象,此時obj的屬性變成只讀,不能添加、改變或刪除屬性(所有屬性都不可配置),其[[Extensible]]值為false,[[Configurable]]值為false。可以利用Object.isSealed(obj)來檢測obj是否被封印。
Object.freeze(obj):凍結(jié)對象,不能在凍結(jié)對象上添加或刪除屬性,不能改變屬性類型,也不能寫入任何數(shù)據(jù)類型。可以利用Object.isFrozen(obj)來檢測obj是否被凍結(jié)。
注意:凍結(jié)對象和封印對象均要在嚴(yán)格模式下使用。
"use strict"; var per5 = { name:"Pomy" }; console.log(Object.isExtensible(per5)); //true console.log(Object.isSealed(per5)); //false console.log(Object.isFrozen(per5)); //false Object.freeze(per5); console.log(Object.isExtensible(per5)); //false console.log(Object.isSealed(per5)); //true console.log(Object.isFrozen(per5)); //true per5.name="dwqs"; console.log(per5.name); //"Pomy" per5.Hi = function(){ console.log("Hi"); }; console.log("Hi" in per5); //false delete per5.name; console.log(per5.name); //"Pomy" var desc = Object.getOwnPropertyDescriptor(per5,"name"); console.log(desc.configurable); //false console.log(desc.writable); //false
注意,禁止修改對象的三個方法只對對象的自有屬性有效,對原型對象的屬性無效,仍然可以在原型上添加或修改屬性。
function Person(name){ this.name = name; } var person1 = new Person("Pomy"); var person2 = new Person("dwqs"); Object.freeze(person1); Person.prototype.Hi = function(){ console.log("Hi"); }; person1.Hi(); //"Hi"; person2.Hi(); //"Hi";
原文:http://www.ido321.com/1585.html
相關(guān)文章:
DOM筆記(九):引用類型、基本包裝類型和單體內(nèi)置對象
DOM筆記(十一):JavaScript對象的基本認(rèn)識和創(chuàng)建
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/85732.html
摘要:使用時,會自動創(chuàng)建對象,其類型為構(gòu)造函數(shù)類型,指向?qū)ο髮嵗鄙訇P(guān)鍵字,指向全局對象。構(gòu)造函數(shù)本身也具有屬性指向原型對象。 在JavaScript面向?qū)ο缶?一)中講解了一些與面向?qū)ο笙嚓P(guān)的概念和方法,這篇講講原型和繼承。 構(gòu)造函數(shù)和原型對象 構(gòu)造函數(shù)也是函數(shù),用new創(chuàng)建對象時調(diào)用的函數(shù),與普通函數(shù)的一個區(qū)別是,其首字母應(yīng)該大寫。但如果將構(gòu)造函數(shù)當(dāng)作普通函數(shù)調(diào)用(缺少new關(guān)鍵字...
摘要:面向?qū)ο缶x書筆記下面代碼的實際執(zhí)行過程是什么使用原始值和原始封裝類型是有區(qū)別的因為是被解析成一個對象的,所以肯定是真的函數(shù)是對象,函數(shù)有兩種字面形式,第一種是函數(shù)聲明,以關(guān)鍵字開頭后面跟函數(shù)名字。 Javascript面向?qū)ο缶x書筆記 1、下面代碼的實際執(zhí)行過程是什么? var name = fan var str = name.charAt(0) console.l...
摘要:解除引用的最佳手段是將對象變量設(shè)置為。字面形式允許你在不需要使用操作符和構(gòu)造函數(shù)顯示創(chuàng)建對象的情況下生成引用值。函數(shù)就是值可以像使用對象一樣使用函數(shù)因為函數(shù)本來就是對象,構(gòu)造函數(shù)更加容易說明。 JavaScript(ES5)的面向?qū)ο缶?標(biāo)簽: JavaScript 面向?qū)ο?讀書筆記 2016年1月16日-17日兩天看完了《JavaScript面向?qū)ο缶罚▍⒓赢惒缴鐓^(qū)的活動送...
摘要:與使用作為接口的唯一標(biāo)識類似,使用稱之為的一個字節(jié)無符號整數(shù)作為唯一標(biāo)識。接口是客戶程序和組件程序之間的橋梁,接口應(yīng)該具有不變性,并且一個對象也應(yīng)該支持多個接口。 COM是Component Object Model (組件對象模型)的縮寫。BREW基本上遵從COM這一組件構(gòu)架的。組...
閱讀 1459·2021-11-22 13:52
閱讀 1281·2021-09-29 09:34
閱讀 2690·2021-09-09 11:40
閱讀 3031·2019-08-30 15:54
閱讀 1255·2019-08-30 15:53
閱讀 971·2019-08-30 11:01
閱讀 1354·2019-08-29 17:22
閱讀 1943·2019-08-26 10:57