摘要:屬性特性每個屬性與之相關的值可寫可枚舉可配置對象特性原型類擴展標記三類對象內置對象由規范定義的對象或類宿主對象由解釋器所嵌入的宿主環境定義的自定義對象由運行中的代碼創建的對象兩類屬性自有屬性直接在對象中定義的屬性繼承屬性在對象的原型對象中
屬性特性(property attribute):每個屬性與之相關的值:
可寫(writable attribute);
可枚舉(enumerable attribute);
可配置(configurable attribute);
對象特性(object attribute):
原型(prototype);
類(class);
擴展標記(extensible flag);
三類js對象:
內置對象(native object):由ECMAScript規范定義的對象或類;
宿主對象(host object):由js解釋器所嵌入的宿主環境定義的;
自定義對象(user-defined object):由運行中的js代碼創建的對象
兩類屬性:
自有屬性(own property):直接在對象中定義的屬性;
繼承屬性(inherited property):在對象的原型對象中定義的屬性;
1 創建對象三種方法:直接量;new和Object.create()函數;
1.1 對象直接量語法:
var o = {};1.2 通過new創建對象
語法:
var o = new Object();1.3 原型
通過Object.prototype獲得對原型對象的引用
1.4 Object.create()第一個參數是這個對象的原型;第二個可選參數是對對象的屬性進行進一步描述
//創建一個普通的空對象 var o = Object.create(Object.prototype);2 屬性的查詢和設置
[]和.
2.1 作為關聯數組的對象JavaScript對象都是關聯數組(字典、映射、散列等)
2.2 繼承[暫跳]
2.3 屬性訪問錯誤當訪問不存在的對象的屬性就會報錯,可以通過下面方法避免出錯:
var book = {}; var len; if (book.subtitle) { len = book.subtitle.length; } console.log(len); //undefined //或者 var book = {subtitle:"toJSON"}; var len; len = book && book.subtitle && book.subtitle.length; //&&運算符的短路行為 console.log(len); //6 //當左操作數是真值時,“&&”運算符將計算右操作數的值并將其返回作為整個表達式的計算結果2.4 刪除屬性
delete運算符不能刪除繼承屬性
3 檢測屬性5種方法:
in運算符,檢測自有屬性和繼承屬性
var o = {name:"Oliver",age:18,nothing:undefined}; console.log("name" in o); //True console.log("toString" in o); //True console.log("nothing" in o); //True
hasOwnProperty方法,檢測自有屬性
var o = {name:"Oliver",age:18,nothing:undefined}; console.log(o.hasOwnProperty("toString")); //False console.log(o.hasOwnProperty("name")); //True
propertyIsEnumerable方法,檢測自有可枚舉的屬性
var o = {name:"Oliver",age:18,nothing:undefined}; console.log(o.propertyIsEnumerable("toString")); //False console.log(o.propertyIsEnumerable("name")); //True
"!=="方法,檢測屬性是否為undefined
var o = {name:"Oliver",age:18,nothing:undefined}; console.log(o.name !== undefined); //True console.log(o.nothing !== undefined); //False
有一種場景只能使用in運算符。in可以區分不存在的屬性和存在但是值為undefined的屬性:
var o = {name:"Oliver",age:18,nothing:undefined}; console.log("nothing" in o); //True console.log(o.nothing !== undefined); //False delete o.nothing; console.log("nothing" in o); //False console.log(o.nothing !== undefined); //False
需要注意的是,"!=="可以區分undefined和null
4 枚舉屬性把p中的可枚舉屬性賦值到o中,并返回o,如果有同名屬性則覆蓋o中的屬性
function extend (o, p) { for (var prop in p) { o[prop] = p[prop]; } return o; }
如:
var p = {name:"Oliver",age:18,nothing:undefined}; var o = {}; function extend (o, p) { for (var prop in p) { o[prop] = p[prop]; } return o; } console.log(extend(o,p));
將p中的可枚舉屬性復制到o中,并返回o,如果有同名屬性則不覆蓋o中的屬性
function merge (o, p) { for (var prop in p) { if (o.hasOwnProperty(prop)) { continue; o[prop] = p[prop]; } } return o; }
如:
var p = {name:"Oliver",age:18,nothing:undefined}; var o = {name:"Oli"}; function merge (o, p) { for (var prop in p) { if (o.hasOwnProperty(prop)) { continue; o[prop] = p[prop]; } } return o; } console.log(merge(o,p).name); //Oli
如果o中的屬性在p中沒有同名屬性,則從o中刪除這個屬性
function restrict (o, p) { for (var prop in o) { if (!(prop in p)) { delete o[prop]; } } return o; }
如:
var p = {age:18,nothing:undefined}; var o = {name:"Oli"}; function restrict (o, p) { for (var prop in o) { if (!(prop in p)) { delete o[prop]; } } return o; } console.log(merge(o, p).name); //undefined
如果o中的屬性在p中存在同名屬性,則從o中刪除這個屬性
function subtract (o, p) { for (var prop in o) { if (prop in p) { delete o[prop]; } } return o; }
如:
var p = {name:"Oliver",age:18,nothing:undefined}; var o = {name:"Oli"}; function subtract (o, p) { for (var prop in o) { if (prop in p) { delete o[prop]; } } return o; } console.log(subtract(o, p).name); //undefined
返回一個新對象,這個對象同時擁有o的屬性和p的屬性,如果有重名屬性,使用p中的屬性值
function union (o, p) { for (var prop in o) { if (prop in p) { o[prop] = p[prop] } } return o; }
如:
var p = {name:"Oliver",age:18,nothing:undefined}; var o = {name:"Oli"}; function union (o, p) { for (var prop in o) { if (prop in p) { o[prop] = p[prop] } } return o; } console.log(union(o, p).name); //Oliver
返回一個新對象,這個對象同時擁有o的屬性和p的屬性,如果重名,使用o的值
function intersection (o, p) { for (var prop in o) { if (prop in p) { delete p[prop]; } } return o; }
如:
var p = {name:"Oliver",age:18,nothing:undefined}; var o = {name:"Oli"}; function intersection (o, p) { for (var prop in o) { if (prop in p) { delete p[prop]; } } return o; } console.log(intersection(o, p).name); //Oliver
返回一個數組,這個數組包含的是o中可枚舉的自有屬性的名字
5 屬性getter和setter存取器屬性(accessor property):由getter和setter定義的屬性;它不同于數據屬性(data property),數據屬性只有一個簡單的值;
語法:
var o = { data_prop: value,/*這是普通數據屬性*/ get accessor_prop(){/*這里是函數體*/}, set accessor_prop(value){/*這里是函數體*/} };
這個定義沒有使用function關鍵字,而是使用get和(或)set
存取器屬性是可以繼承的
var o = { n: 0,/*這是普通數據屬性*/ get next(){return this.n++}, set next(n){this.n = n} }; o.next = 10; //setter console.log(o.next) //getter6 屬性的特性
存取器屬性的四個特性:讀取(get)、寫入(set)、可枚舉性(enumerable)和可配置性(configurable)
數據屬性的四個特性:值(value)、可寫性(writable)、可枚舉性(enumerable)和可配置性(configurable)
獲得某個對象特定屬性的屬性描述符
Object.getOwnPropertyDescriptor()方法:
//name數據屬性 let o = { name: "Oliver", get transferName(){return this.name}, set transferName(value){this.name = name} }; let result = Object.getOwnPropertyDescriptor(o, "name"); console.log(result); //Object for (let name in result) { console.log(name, result[name]); } //value Oliver //writable True //enumerable True //configurable True //transferName存取器屬性 let o = { name: "Oliver", get transferName(){return this.name}, set transferName(value){this.name = name} }; let result = Object.getOwnPropertyDescriptor(o, "transferName"); console.log(result); //Object for (let name in result) { console.log(name, result[name]); } //get function transferName(){return this.name} //set function transferName(value){this.name = name} //enumerable True //configurable True
設置屬性的特性
Object.defineProperty()方法:
let o = { name: "Oliver", get transferName(){return this.name}, set transferName(value){this.name = name} }; let result = Object.getOwnPropertyDescriptor(o, "name"); console.log(result); //Object for (let name in result) { console.log(name, result[name]); } //value Oliver //writable True //enumerable True //configurable True Object.defineProperty(o, "name", { value: "Oli", writable: false, enumerable: false, configurable: false }); let result1 = Object.getOwnPropertyDescriptor(o, "name"); console.log(result1); //Object for (let name in result1) { console.log(name, result1[name]); } //value Oli //writable False //enumerable False //configurable False
該方法不能修改繼承屬性
設置多個屬性特性
Object.defineProperties()方法:
語法:Object.defineProperties(Object, props)
var obj = {}; Object.defineProperties(obj, { x: {value: 1, writable: false, enumerable: true, configurable: false}, y: {get: function(){return this.x}, enumerable: true, configurable: false} }); console.log(obj.y); //1 console.log(obj.x); //1 obj.x = 2; console.log(obj.x); //嚴格模式下報錯
老式API
在ES5之前,需要用到
__lookupGetter()__
__lookupSetter()__
__defineGetter()__
__defineSetter()__
7 對象的三個屬性原型(prototype)
類(class)
可擴展性(extensible)
7.1 原型屬性對象的原型屬性是用來繼承屬性的
var obj = {}; console.log(obj.constructor); //function Object(){ [native code] } console.log(obj.__proto__); //Object console.log(Object); //function Object(){ [native code] } console.log(Object.prototype); //Object console.log(Object.prototype.isPrototypeOf(obj)); //True
檢測一個對象是否是另一個對象的原型
isPrototypeOf()方法
var obj = {}; var anotherObj = Object.create(obj); console.log(Object.prototype.isPrototypeOf(obj)); //True console.log(obj.isPrototypeOf(anotherObj)); //True7.2 類屬性
是一個字符串,用以表示對象的類型信息,默認的toString()方法很有可能被修改,所以應該使用下面的classof函數:
查詢類
使用classof()函數:
function classof (o) { if (o === null) { return "Null"; } if (o === undefined) { return "Undefined"; } return Object.prototype.toString.call(o).slice(8, -1); }
例如:
console.log(classof(obj)); //Object console.log(classof(Number)); //Function console.log(classof(123)); //Number7.3 可擴展性
可擴展性表示是否可以給對象添加新屬性
設置為不可擴展,檢測是否不可擴展
Object.preventExtensions()設置為對象不可擴展
Object.isExtensible()檢測是否可擴展
var obj = { name: "Oliver" }; Object.preventExtensions(obj); obj.name = "Oli"; //可修改屬性的值 delete obj.name; //可配置屬性 obj.age = 18; //不可擴展 嚴格模式下報錯
設置為不可擴展且不可配置,檢測是否不可擴展且不可配置
Object.seal()
Object.isSealed()
var obj = { name: "Oliver" }; Object.seal(obj); obj.name = "Oli"; //可修改屬性的值 delete obj.name; //不可配置屬性 嚴格模式下報錯 obj.age = 18; //不可擴展 嚴格模式下報錯
設置為不可擴展、不可配置且所有數據屬性設置為只讀(setter不受影響),以及檢測方法
Object.freeze()
Object.isFrozen()
var obj = { name: "Oliver", anotherObj: { name: "Oliver" }, set setName (value) { this.name = value; } }; Object.freeze(obj); obj.anotherObj.name = "Oli"; //可以修改屬性值為對象的子對象的屬性 obj.setName = "Oli"; //不可修改setter屬性的值 obj.name = "Oli"; //不可修改屬性的值 delete obj.name; //不可配置屬性 嚴格模式下報錯 obj.age = 18; //不可擴展 嚴格模式下報錯8 序列化對象
對象序列化(serialization):將對象的狀態轉換為字符串,或將字符串還原成對象;
JSON.stringify()
JSON.parse()
JSON(JavaScript Object Notation):JavaScript對象表示法;
var date = new Date(); console.log(date.toString()); //與JSON.stringify()的返回值不同 console.log(date.toJSON()); //與JSON.stringify()的返回值一樣9 對象方法
toString方法
toLocaleString方法
toJSON方法(嚴格意義上不算對象原型的方法)
valueOf方法(用在需要將它轉換成某種原始值而非字符串的時候)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79051.html
摘要:簡介原文鏈接簡稱是一種輕量級,解釋型的編程語言,其函數是一等公民。標準的目標是讓任何一種程序設計語言能操控使用任何一種標記語言編寫出的任何一份文檔。核心規定了如何映射基于的文檔結構,以便簡化對文檔的任意部分的訪問和操作。 JavaScript 簡介 原文鏈接 JavaScript ( 簡稱:JS ) 是一種 輕量級,解釋型 的編程語言,其函數是一等公民。眾所周知,它是用于網頁開發的腳...
摘要:舉個例子在上面的例子可以看到,我們聲明是一個數字,但是我們在之后將的值又改成了字符串和布爾值后面會講這些類型。基本類型字符串表示一個字符串,如。因此,我們可以寫一個函數,用來精確檢測類型。 showImg(https://segmentfault.com/img/remote/1460000017309509?w=850&h=572); 定義 1. 什么是數據類型? 數據類型,就是將...
摘要:不過讓流行起來的原因應該是是目前所有主流瀏覽器上唯一支持的腳本語言。經過測試,數字字符串布爾日期可以直接賦值,修改不會產生影響。再考慮對象類型為或者的情況。對于結果聲明其類型。判斷對象的類型是還是,結果類型更改。 轉載自我的個人博客 歡迎大家批評指正 1. 第一個頁面交互 這里最需要學習的老師的代碼中,每一部分功能都由函數控制,沒有創建一個全部變量。且最后有一個函數來控制執行代碼...
摘要:更形象的我們還可以將面向對象理解為一種宗教信仰。這就導致面向對象教的程序員們在寫時就很難受。所以為了滿足信仰面向對象教的需求通過構造函數的形式模擬了偽類。這個套路的核心就是類那么里沒有類所以其實是通過構造函數來模擬的偽類。 JS面向對象之一 【概述】 在學習JS的面向對象之前,我們應該先自問這樣幾個問題: 面向對象是什么意思? 學習面向對象的核心是什么? 為什么要學習面向對象?(它的...
摘要:在同一個塊內,不允許用重復聲明變量。中為新增了塊級作用域。自帶遍歷器的對象有數組字符串類數組對象對象的對象等和結構對象。返回一個遍歷器,使遍歷數組的鍵值對鍵名鍵值。 目錄 1.語法 2.類型、值和變量 3.表達式和運算符 4.語句 5.數組 6.對象 7.函數 8.全局屬性和方法 9.詞法作用域、作用域鏈、閉包 10.原型鏈、繼承機制 11.this的理解 12.ES5新特性 13.E...
摘要:原始表達式直接量保留字變量原始表達式表達式的最小單位表達式中的短語,解釋器會將其計算為一個結果對象和數據的初始化表達式對象直接量和數組直接量,它們和布爾直接量不同,它們不是原始表達式函數定義表達式函數直接量也不是原始表達式屬性訪問表達式語法 1 原始表達式 直接量、保留字、變量 原始表達式(primary expression):表達式的最小單位 表達式:JavaScript中的短語...
閱讀 704·2021-11-22 13:54
閱讀 3065·2021-09-26 10:16
閱讀 3490·2021-09-08 09:35
閱讀 1576·2019-08-30 15:55
閱讀 3429·2019-08-30 15:54
閱讀 2076·2019-08-30 10:57
閱讀 497·2019-08-29 16:25
閱讀 877·2019-08-29 16:15