【前端基礎進階】JS-Object 功能詳解

clipboard.png

Object.assign(target,source1,source2,...)

該方法主要用于對象的合并,將源對象source的所有可枚舉屬性合并到目標對象target上,此方法只拷貝源對象的自身屬性,不拷貝繼承的屬性。
Object.assign方法實行的是淺拷貝,而不是深拷貝。也就是說,如果源對象某個屬性的值是對象,那么目標對象拷貝得到的是這個對象的引用。同名屬性會替換。

Object.assign只能進行值的復制,如果要復制的值是一個取值函數,那么將求值后再復制。

Object.assign可以用來處理數組,但是會把數組視為對象。

const target = {x : 0,y : 1
};
const source = {x : 1,z : 2 ,fn : {number : 1}
};
Object.assign(target, source);  
// target  {x : 1, y : 1, z : 2, fn : {number : 1}}    // 同名屬性會被覆蓋
// source  {x : 1, z : 2, fn : {number : 1}}
target.fn.number = 2;                                  // 拷貝為對象引用
// source  {x : 1, z : 2, fn : {number : 2}}function Person(){this.name = 1
};
Person.prototype.country = 'china';
let student = new Person();
student.age = 29 ;
const young = {insterst : 'sport'};
Object.assign(young,student);
// young {instest : 'sport' , age : 29, name: 1}               // 只能拷貝自身的屬性,不能拷貝prototypeObject.assign([1, 2, 3], [4, 5])                      // 把數組當作對象來處理
// [4, 5, 3]

Object.create(prototype[,propertiesObject])

使用指定的原型對象及其屬性去創建一個新的對象

var parent = {x : 1,y : 1
}
var child = Object.create(parent,{z : {                           // z會成為創建對象的屬性writable:true,configurable:true,value: "newAdd"}
});
console.log(child)

clipboard.png


Object.defineProperties(obj,props)

直接在一個對象上定義新的屬性或修改現有屬性,并返回該對象。

var obj = {};
Object.defineProperties(obj, {'property1': {value: true,writable: true},'property2': {value: 'Hello',writable: false}// etc. etc.
});
console.log(obj)   // {property1: true, property2: "Hello"}

Object.defineProperty(obj,prop,descriptor)

在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 并返回這個對象。

Object.defineProperty(obj, 'is', {value: function(x, y) {if (x === y) {// 針對+0 不等于 -0的情況return x !== 0 || 1 / x === 1 / y;}// 針對NaN的情況return x !== x && y !== y;},configurable: true, //是否可刪除enumerable: false, //是否可forin枚舉writable: true //是否為只讀
}); 
console.log(obj)// 注意不能同時設置(writable,value) 和 get,set方法,否則瀏覽器會報錯 : Invalid property descriptor. Cannot both specify accessors and a value or writable attribute

Object.getOwnPropertyDescriptor()

功能:
該方法返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)

語法: Object.getOwnPropertyDescriptor(obj, prop)
obj: 需要查找的目標對象
prop: 目標對象內屬性名稱

var person = {name: '張三',age: 18
}var desc = Object.getOwnPropertyDescriptor(person, 'name'); 
console.log(desc)  結果如下
// {
//     configurable: true,
//     enumerable: true,
//     writable: true,
//     value: "張三"
// }

ps

Object的defineProperty和defineProperties這兩個方法在js中的重要性十分重要,主要功能就是用來定義或修改這些內部屬性,與之相對應的getOwnPropertyDescriptor和getOwnPropertyDescriptors就是獲取這行內部屬性的描述。

例如

在對象中添加存取描述符屬性
var obj = {};
var aValue; //如果不初始化變量, 不給下面的a屬性設置值,直接讀取會報錯aValue is not defined
var b;
Object.defineProperty(obj, 'a', {configurable : true,enumerable : true,get: function() {return aValue},set: function(newValue) {aValue = newValue;b = newValue + 1}
})
console.log(b) // undefined
console.log(obj.a)  // undefined, 當讀取屬性值時,調用get方法,返回undefined
obj.a = 2;  // 當設置屬性值時,調用set方法,aValue為2console.log(obj.a) // 2  讀取屬性值,調用get方法,此時aValue為2
console.log(b) // 3  再給obj.a賦值時,執行set方法,b的值被修改為2,額外說一句,vue中的計算屬性就是利用setter來實現的

vue的核心正是如此

簡易的數據雙向綁定

html代碼:

<body><p>input1=><input type="text" id="input1"></p><p>input2=><input type="text" id="input2"></p><div>我每次比input1的值加1=><span id="span"></span></div>
</body>
js代碼:var oInput1 = document.getElementById('input1');
var oInput2 = document.getElementById('input2');
var oSpan = document.getElementById('span');
var obj = {};
Object.defineProperties(obj, {val1: {configurable: true,get: function() {oInput1.value = 0;oInput2.value = 0;oSpan.innerHTML = 0;return 0},set: function(newValue) {oInput2.value = newValue;oSpan.innerHTML = Number(newValue) ? Number(newValue) : 0}},val2: {configurable: true,get: function() {oInput1.value = 0;oInput2.value = 0;oSpan.innerHTML = 0;return 0},set: function(newValue) {oInput1.value = newValue;oSpan.innerHTML = Number(newValue)+1;}}
})
oInput1.value = obj.val1;
oInput1.addEventListener('keyup', function() {obj.val1 = oInput1.value;
}, false)
oInput2.addEventListener('keyup', function() {obj.val2 = oInput2.value;
}, false)

Object.keys(obj)

返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致 (兩者的主要區別是 一個 for-in 循環還會枚舉其原型鏈上的屬性)。

let arr = ["a", "b", "c"];
console.log(Object.keys(arr));
// ['0', '1', '2']/* Object 對象 */
let obj = { foo: "bar", baz: 42 },keys = Object.keys(obj);
console.log(keys);
// ["foo","baz"] 

Object.values()

方法返回一個給定對象自己的所有可枚舉屬性值的數組,值的順序與使用for...in循環的順序相同 ( 區別在于 for-in 循環枚舉原型鏈中的屬性 )。

Object.values會過濾屬性名為 Symbol 值的屬性。

var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

Object.entries()

返回一個給定對象自身可枚舉屬性的鍵值對數組,其排列與使用 for...in 循環遍歷該對象時返回的順序一致(區別在于 for-in 循環也枚舉原型鏈中的屬性)。

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]const simuArray = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(simuArray)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
hasOwnProperty() 判斷對象自身屬性中是否具有指定的屬性。
obj.hasOwnProperty('name')

Object.getOwnPropertyDescriptor(obj,prop)

返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性).

如果指定的屬性存在于對象上,則返回其屬性描述符對象(property descriptor),否則返回 undefined。

var arr = ['name','age'] ;
arr.forEach(val => console.log(Object.getOwnPropertyDescriptor(obj,val)))// {value: "js", writable: true, enumerable: true, configurable: true}
// undefined

Object.getOwnPropertyDescriptors(obj)

獲取一個對象的所有自身屬性的描述符。

var obj = {name : 'js',age : 20
}
console.log(Object.getOwnPropertyDescriptors(obj))const source = {set foo(value) {console.log(value);}
};const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target2, 'foo')const obj = Object.create(some_obj,Object.getOwnPropertyDescriptors({foo: 123,})
);

Object.getOwnPropertyNames()

返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數組。

var obj = { 0: "a", 1: "b", 2: "c"};Object.getOwnPropertyNames(obj).forEach(function(val) {console.log(val);
});var obj = {x : 1,y : 2
}Object.defineProperty(obj,'z',{enumerable : false
})
console.log(Object.getOwnPropertyNames(obj))  // ["x", "y", "z"] 包含不可枚舉屬性 。
console.log(Object.keys(obj))                 // ["x", "y"]      只包含可枚舉屬性 。

Object.getOwnPropertySymbols()
返回一個給定對象自身的所有 Symbol 屬性的數組。


Object.getPrototypeOf()
返回指定對象的原型(內部[[Prototype]]屬性的值,即__proto__,而非對象的prototype)。


Object.isPrototypeOf()
判斷一個對象是否存在于另一個對象的原型鏈上。


Object.setPrototypeOf(obj,prototype)
設置對象的原型對象


Object.is()

判斷兩個值是否相同。
如果下列任何一項成立,則兩個值相同:

兩個值都是 undefined
兩個值都是 null
兩個值都是 true 或者都是 false
兩個值是由相同個數的字符按照相同的順序組成的字符串
兩個值指向同一個對象
兩個值都是數字并且
都是正零 +0
都是負零 -0
都是 NaN
都是除零和 NaN 外的其它同一個數字

Object.is('foo', 'foo');     // true
Object.is(window, window);   // trueObject.is('foo', 'bar');     // false
Object.is([], []);           // falsevar test = { a: 1 };
Object.is(test, test);       // trueObject.is(null, null);       // true// 特例
Object.is(0, -0);            // false
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true

Object.freeze()

凍結一個對象,凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。也就是說,這個對象永遠是不可變的。該方法返回被凍結的對象。

var obj = {prop: function() {},foo: 'bar'
};// 新的屬性會被添加, 已存在的屬性可能
// 會被修改或移除
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;// 作為參數傳遞的對象與返回的對象都被凍結
// 所以不必保存返回的對象(因為兩個對象全等)
var o = Object.freeze(obj);o === obj; // true
Object.isFrozen(obj); // === true// 現在任何改變都會失效
obj.foo = 'quux'; // 靜默地不做任何事
// 靜默地不添加此屬性
obj.quaxxor = 'the friendly duck';
console.log(obj)

Object.isFrozen()
判斷一個對象是否被凍結 .


Object.preventExtensions()
對象不能再添加新的屬性。可修改,刪除現有屬性,不能添加新屬性。


var obj = {name :'lilei',age : 30 ,sex : 'male'
}obj = Object.preventExtensions(obj);
console.log(obj);    // {name: "lilei", age: 30, sex: "male"}
obj.name = 'haha';
console.log(obj)     // {name: "haha", age: 30, sex: "male"}
delete obj.sex ;
console.log(obj);    // {name: "haha", age: 30}
obj.address  = 'china';
console.log(obj)     // {name: "haha", age: 30}

Object.isExtensible()

判斷對象是否是可擴展的,Object.preventExtensions,Object.seal 或 Object.freeze 方法都可以標記一個對象為不可擴展(non-extensible)


Object.seal()

Object.seal() 方法可以讓一個對象密封,并返回被密封后的對象。密封一個對象會讓這個對象變的不能添加新屬性,且所有已有屬性會變的不可配置。屬性不可配置的效果就是屬性變的不可刪除,以及一個數據屬性不能被重新定義成為訪問器屬性,或者反之。但屬性的值仍然可以修改。嘗試刪除一個密封對象的屬性或者將某個密封對象的屬性從數據屬性轉換成訪問器屬性,結果會靜默失敗或拋出TypeError 異常. 不會影響從原型鏈上繼承的屬性。但 proto ( ) 屬性的值也會不能修改。

var obj = {prop: function () {},foo: "bar"};// 可以添加新的屬性,已有屬性的值可以修改,可以刪除
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;var o = Object.seal(obj);assert(o === obj);
assert(Object.isSealed(obj) === true);// 仍然可以修改密封對象上的屬性的值.
obj.foo = "quux";// 但你不能把一個數據屬性重定義成訪問器屬性.
Object.defineProperty(obj, "foo", { get: function() { return "g"; } }); // 拋出TypeError異常// 現在,任何屬性值以外的修改操作都會失敗.
obj.quaxxor = "the friendly duck"; // 靜默失敗,新屬性沒有成功添加
delete obj.foo; // 靜默失敗,屬性沒有刪除成功// ...在嚴格模式中,會拋出TypeError異常
function fail() {"use strict";delete obj.foo; // 拋出TypeError異常obj.sparky = "arf"; // 拋出TypeError異常
}
fail();// 使用Object.defineProperty方法同樣會拋出異常
Object.defineProperty(obj, "ohai", { value: 17 }); // 拋出TypeError異常
Object.defineProperty(obj, "foo", { value: "eit" }); // 成功將原有值改變

Object.isSealed()
判斷一個對象是否被密封

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280156.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280156.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280156.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決“無法從套接字讀取更多數據”

重啟下Oralce服務即可。轉載于:https://www.cnblogs.com/fkeyta/p/9153297.html

網頁下載Google Play 的App

網頁下載Google Play 的App 文章目錄[點擊展開](?)[] 前言 當你想在google play上下載某個應用&#xff0c;而無奈手機的系統并沒有安裝google servicess&#xff0c;此刻是否有些捉急&#xff1f; 本文分享的是一個網站&#xff0c;它可以無需手機而直接通過網頁下載Google P…

“硬核”代碼重構

在學習編程的路上&#xff0c;相信大家這幾個詞一定不少聽&#xff0c;什么 面相對象、封裝繼承多態、內功心法21種設計模式 等等 。但是卻很少用到&#xff0c;或者說用到的都是被動使用。大牛們在寫代碼前早就構思好了&#xff0c;接口&#xff0c;基類等等。自己寫代碼的時候…

上傳jar包到nexus私服

進入maven管理頁面&#xff0c;登錄管理員賬號 完成后可以進入對應目錄下查看pom依賴 通過maven的方式depoly 在maven的conf/setting.xml 配置nexus私服的管理賬號 在servers標簽下添加server <server><id>nexus-snapshots</id><username>repouser<…

手把手教你寫高質量Android技術博客,畫圖工具,錄像工具,Markdown寫法

前言 作為程序員&#xff0c;寫博客是一件很有意義的事情&#xff0c;可以加深自己對技術的理解&#xff0c;可以結交更多的朋友&#xff0c;記錄自己的技術軌跡&#xff0c;而且分享可以讓更多的人從中受益&#xff0c;獨樂樂不如眾樂樂嘛。 但是要寫好博客也不是件容易的事&a…

【Android】RxJava的使用(四)線程控制 —— Scheduler

前言 經過前幾篇的介紹&#xff0c;對RxJava對模式有了一定的理解&#xff1a;由Observable發起事件&#xff0c;經過中間的處理后由Observer消費。&#xff08;對RxJava還不了解的可以出門左拐&#xff09;之前的代碼中&#xff0c;事件的發起和消費都是在同一個線程中執行&am…

sed: -e expression #1, unknown option to `s'解決辦法

報錯如下&#xff1a; sed: -e expression #1, char 13: unknown option to s 需要替換的行為&#xff1a; monitor.urlhttp://192.168.25.100:8443/rest 查詢資料得知&#xff0c;報錯是因為替換的字符串包含有分隔符/ 所以這行改一下分隔符就可以解決問題了 改成感嘆號!或者|…

Linux常用開發環境軟件-Redis安裝(docker環境下)

linux&#xff0c;docker安裝RabbitMQ版本 1、從docker官網倉庫下載安裝RabbitMQ鏡像 官網地址&#xff1a;https://hub.docker.com/ docker pull redis:4.0.8  //后面是版本,Tag Name 2、啟動Docker Redis鏡像 docker run -d -p 6379:6379 redis:4.0.8  啟動鏡像&#xff…

以當天日期時間,打包目錄

#備份/data目錄#!/bin/bash DATEdate %Y-%m-%d-%H:%M:%S tar cvf /mnt/resource/script/prod_master_data.$DATE.tar.gz /data[root111 script]# ll total 2536 -rw-r--r-- 1 root root 2590720 Feb 22 21:46 prod_master_data.2019-02-22-21:46:53.tar.gz轉載于:https://blog.…

lvs+keepalived詳解

常用軟件安裝及使用目錄 資源鏈接&#xff1a;https://pan.baidu.com/s/15rFjO-EnTOyiTM7YRkbxuA 網盤分享的文件在此 官網&#xff1a;http://www.linuxvirtualserver.org/index.html 中文資料 LVS項目介紹 http://www.linuxvirtualserver.org/zh/lvs1.html …

微信自動打卡

要有第二臺安卓 手機&#xff0c;打開usb、adb調試&#xff0c;永不鎖屏&#xff0c;永不休眠&#xff0c;手機安裝了微信并至少成功登陸過一次&#xff0c; 一臺不關機的電腦&#xff0c;手機連接電腦&#xff0c;Appium服務器保持啟動&#xff0c;在開始菜單 設定好任務計劃程…

利用反射做類參數的校驗

需求描述 業務需求描述&#xff1a;對webservice接口參數校驗 代碼實現 /*** 字符串長度校驗* * param str* param len* return 合法(true),不合法(false)*/public static boolean check(String str, int len) {if (null ! str && str.length() > len) {return fals…

跨域的四種方式

本文主要是關于跨域的幾種方式&#xff0c;關于什么是跨域這里就不多說了&#xff0c;寫這個也是為了記住一些知識點的。 一. jsonp jsonp的跨域方式很容易理解&#xff0c;頁面的的每一個script標簽瀏覽器都會發送get請求獲取對應的文本資源&#xff0c;獲取到了之后&#xff…

Linux之read命令使用

ead命令&#xff1a; read 命令從標準輸入中讀取一行&#xff0c;并把輸入行的每個字段的值指定給 shell 變量 1&#xff09;read后面的變量var可以只有一個&#xff0c;也可以有多個&#xff0c;這時如果輸入多個數據&#xff0c;則第一個數據給第一個變量&#xff0c;第二個數…

python之路day10-命名空間和作用域、函數嵌套,作用域鏈、閉包

楔子 假如有一個函數&#xff0c;實現返回兩個數中的較大值&#xff1a; def my_max(x,y):m x if x>y else yreturn mbigger my_max(10,20)print(bigger) 之前是不是我告訴你們要把結果return回來你們就照做了&#xff1f;可是你們有沒有想過&#xff0c;我們為什么要把結…

hive(II)--sql考查的高頻問題

在了解別人hive能力水平的時候&#xff0c;不管是別人問我還是我了解別人&#xff0c;有一些都是必然會問的東西。問的問題也大都大同小異。這里總結一下我遇到的那些hive方面面試可能涉及的問題 1、行轉列&#xff08;列轉行&#xff09; 當我們建設數據倉庫時&#xff0c;我們…

java概述

一、java平臺無關&#xff1a;jvm二、java健壯語言&#xff1a;無指針&#xff0c;語法上無指正&#xff0c;無內存申請與釋放。 三、java核心機制而&#xff1a; jvmjava垃圾收集機制 GC四、java運行過程&#xff1a;源程序&#xff08;.java&#xff09;——》java編譯器——…

時間間隔

計算當前時間與上次執行時間的時間間隔。 NSTimeInterval timetravel [[NSDate date]timeIntervalSinceDate:self.lastPlaySoundDate];if (timetravel<3.0) {DLog("時間太短&#xff0c;。。");}self.lastPlaySoundDate [NSDate date]; 轉載于:https://www.cnb…

.Net+MySQL組合開發(二) 數據訪問篇

一、建立數據庫、表、添加數據這里我們使用圖形化操作的SQL Manager 2005 Lite for MySQL來建立數據&#xff0c;它的操作界面非常類似OFFICE軟件&#xff0c;使用方便、很容量上手、下面開始建立數據庫及表單擊"Creat New DataBase"&#xff1a;新建DB輸入密碼&…

Git vs SVN

一、Git vs SVN Git 和 SVN 孰優孰好&#xff0c;每個人有不同的體驗。Git是分布式的&#xff0c;SVN是集中式的這是 Git 和 SVN 最大的區別。若能掌握這個概念&#xff0c;兩者區別基本搞懂大半。因為 Git 是分布式的&#xff0c;所以 Git 支持離線工作&#xff0c;在本地可以…