走在前端的大道上javascript
最后更新 2018.12.27html
本篇将本身读过的相关 javascript Object方法 文章中,对本身有启发的章节片断总结在这(会对原文进行删改),会不断丰富提炼总结更新。前端
返回一个数组,包括对象自身的(不含继承的)全部可枚举属性
示例代码:vue
(1) 数组Array对象(返回索引值)java
var arr=[1,2,3]; Object.keys(arr) // ["0", "1", "2”]
(2) object对象(返回key值)面试
var obj = { foo: "bar", baz: 42 }; Object.keys(obj) // ["foo", "baz”]
(3) 类数组,对象segmentfault
var obj = { 0 : "a", 1 : "b", 2 : "c”}; Object.keys(obj) // ["0", "1", "2"]
(4) 类数组对象 随机key排序api
var Obj = { 100: 'a’, 2: 'b’,7: 'c’ }; console.log(Object.keys(Obj)); // ['2', '7', '100’]. 返回从小到大排序后的结果
(5) Object.keys仅遍历对象自己,并将全部可枚举的属性组合成一个数组返回数组
var Person = function({name='none', age=18, height=170}={}){ this.name = name; this.age = age; this.height = height; } Person.prototype = { type: 'Animal' } var qiu = new Person() // 将height属性设置为 不可枚举 Object.defineProperty(qiu, 'height', { enumerable: false }) var keys = Object.keys(qiu); console.log(keys) // output: ['name', 'age']
(6) 将键值类型的查询param转换成url的query浏览器
const searchObj = { title: 'javascript', author: 'Nicolas', publishing: "O'RELLY", language: 'cn' } let searchStr = Object.keys(searchObj) .map(item => `${item}=${searchObj[item]}`) .join('&'); let url = `localhost:8080/api/test?${searchStr}`
遍历键值对的数据时,使用Object.keys真是不二之选。
方法返回一个给定对象本身的全部可枚举属性值的数组,值的顺序与使用for..in循环相同,返回的对象的value值, 与Object.key()相反
(1) 正常对象
var obj={a:1,b:2,c:3}; console.log(Object.values(obj)) // [1, 2, 3]
(2) 类数组对象
var obj ={0:'a',1:'b',2:'c'}; console.log(Object.values(obj)). // [a,b,c]
(3) key值为无序number
var obj={100:'a',10:'b',1:'1'}; console.log(Object.values(obj)). // ["1", "b", "a"]
返回一个数组,包含对象自身(不含继承)的全部属性名
示例代码:
var Person = function({name='none', age=18, height=170}={}){ this.name = name; this.age = age; this.height = height; } Person.prototype = { type: 'Animal' } var qiu = new Person() // 将height属性设置为 不可枚举 Object.defineProperty(qiu, 'height', { enumerable: false }) var keys = Object.getOwnPropertyNames(qiu); console.log(keys) // output: ['name', 'age', 'height']
与Object.keys的区别在于Object.getOwnPropertyNames会把不可枚举的属性也返回。除此以外,与Object.keys的表现一致。
javascript中提供Object.getPrototypeOf()
方法来得到对象的直接原型。
function Person() { this.name = 'sillywa' } var person1 = new Person() Object.getPrototypeOf(person1) // {constructor: ƒ Person()} Object.getPrototypeOf(person1.__proto__) // Object.prototype var person = { name: 'sillywa' } var person2 = Object.create(person) Object.getPrototypeOf(person2) // {name: "sillywa"}
javascript有如下几种方法检测一个对象的原型:
var obj1 = { name: 'sillywa' } var obj2 = Object.create(obj1) // isPrototypeOf()方法 Object.prototype.isPrototypeOf(obj1) // true obj1.isPrototypeOf(obj2) // true Object.prototype.isPrototypeOf(obj2) // true // obj.constructor.prototype obj1.constructor.prototype === Object.prototype // true // obj1是obj2的原型,如下等式应为true obj2.constructor.prototype === obj1 // false // 而实际上 obj2.constructor.prototype === Object.prototype // true
以上代码中obj1
是obj2
的原型,obj2.constructor.prototype === obj1
应为true
可是实际上倒是false
,由于obj2
的__proto__
里面并无一个constructor
属性,obj2.constructor
其实是obj1
的__proto__
里面的constructor
,因此obj2.constructor.prototype === Object.prototype
。
Object.assign()方法用于将全部可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象,可是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象自己。
Object.assign(target, ...sources)
参数:target
:目标对象;sources
:源对象;
返回值:目标对象
(1) 用来复制一个新对象,并不会影响原对象
var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
(2) 用来合并对象属性,将源对象的全部可枚举属性,复制到目标对象
//object.assign(obj, obj2) obj2是源对象,obj 是目标对象,返回目标对象 var obj = { a: 1 }; var obj2={b:2}; console.log(Object.assign(obj,obj2)===obj); //true,返回目标对象 console.log(obj); //{a:1,b:2} obj的值已被更改
(3) 若是目标对象和源对象中有相同的键,则属性将被源对象的属性覆盖,后面的源属性会覆盖以前的相同键的源属性
var obj = { a: 1 }; var obj2 = {a:5,b:2}; var obj3 = {b:1,d:0}; Object.assign(obj,obj2,obj3); console.log(obj); // {a: 5, b: 1, d: 0}
obj和obj2同时拥有相同的键a,但两个值不一样,obj是目标对象,因此会被源对象obj2的值覆盖,obj2和obj3也同时拥有相同的键b,在拷贝时,obj3排在obj2的后面,因此obj2被覆盖 ,最终打印结果是:{a:5,b:1,d:0}
(4) 当assign只有一个对象时,则直接返回这个对象,不作任何操做
var obj = { a: 1 } Object.assign(obj); console.log(obj); //{a:1}
(5) Object.assign()方法实行的是浅拷贝,而不是深拷贝
也就是说,若是源对象某个属性的值是对象,那么目标对象拷贝获得的是这个对象的引用
var obj1 = { a: 0 , b: { c: 0}}; var obj2 = Object.assign({}, obj1); obj1.b.c=5; console.log(obj2) //{a:0,b:{c:5}};
当咱们在改变obj1的值时,并无想改变obj2,但obj2的值也发生了改变,这违背了咱们的想法。
(6)深拷贝
var obj1 = { a: 0 , b: { c: 0}}; var obj3 = JSON.parse(JSON.stringify(obj1)); obj1.a = 4; obj1.b.c = 4; console.log(obj3); //{ a: 0 , b: { c: 0}};
Object.create() 方法会使用指定的原型对象及其属性去建立一个新的对象。
Object.create(proto[, propertiesObject])
proto 新建立对象的原型对象。
propertiesObject 可选。
若是没有指定为 undefined,不然是要添加到新建立对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。
在指定原型对象上添加新属性后的对象。
若是proto参数不是 null 或一个对象,则抛出一个 TypeError 异常。
var o; // 建立一个原型为null的空对象 o = Object.create(null); o = {}; // 以字面量方式建立的空对象就至关于: o = Object.create(Object.prototype); o = Object.create(Object.prototype, { // foo会成为所建立对象的数据属性 foo: { writable:true, configurable:true, value: "hello" }, // bar会成为所建立对象的访问器属性 bar: { configurable: false, get: function() { return 10 }, set: function(value) { console.log("Setting `o.bar` to", value); } } }); function Constructor(){} o = new Constructor(); // 上面的一句就至关于: o = Object.create(Constructor.prototype); // 固然,若是在Constructor函数中有一些初始化代码,Object.create不能执行那些代码 // 建立一个以另外一个空对象为原型,且拥有一个属性p的对象 o = Object.create({}, { p: { value: 42 } }) // 省略了的属性特性默认为false,因此属性p是不可写,不可枚举,不可配置的: o.p = 24 o.p //42 o.q = 12 for (var prop in o) { console.log(prop) } //"q" delete o.p //false //建立一个可写的,可枚举的,可配置的属性p o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });
咱们知道经过Object.create()
建立的对象实际上等于将该对象的__proto__
指向Object.create()
里面的参数对象,那么当涉及到原型时它是怎么工做的呢?
var a = { name: 'sillywa' } var b = Object.create(a) b.__proto__ === Object.prototype // false b.__proto__ === a // true b.__proto__.constructor === Object // true b.__proto__.hasOwnProperty('constructor') // false
var b = Object.create(a)
其实是把b
的__proto__
指向了a
。当访问b.constructor
时,实际上访问的是b.__proto__.__proto__.constructor
。
咱们要明确一点删除属性的方法只有一个是 delete
,可是在咱们的开发中咱们有时每每将属性值设为 null,undefined 就说成是将属性删除,这是不对的这样作仅仅是取消了属性和值之间的关联。
咱们能够经过 Object.hasOwnProperty()
这个方法来看一看;
let foo = { name: 'foo', firstChild: '1st foo', twoChild: '2th foo' }; foo.name = undefined; // undefined foo.firstChild = null; // null delete foo.twoChild; // true for (let key in foo) { console.log('key:' + key + ', value:' + foo[key]); } /* key:name, value:undefined key:firstChild, value: null */
咱们发现若是用 undefined 和 null 至关于给属性赋值,只有当用 delete 才是删除属性。
注:定义属性的名字时要使用通常的字符串并且是连续的字符串,属性名的定义要避免JavaScript关键字,就像咱们有的公司定的对象属性的访问用 [] , 对象的方法用 . 。
for … in 这个循环体来遍历对象的属性,包括对象原型链上的属性。
let obj = {a:1, b:2, c:3} for (let key in obj) { console.log(obj[key]); } /* 1 2 3 */
// 自定义属性是否可枚举 function customObjectEnumerable(obj, prop, value, flag) { Object.defineProperty(obj, prop, { configurable: true, value: value, enumerable: flag, writable: true }); }; var obj = {}; customObjectEnumerable(obj, a, 1, false); customObjectEnumerable(obj, b, 2, false); for(let key in obj) {console.log(obj[key])} // undefined var obj2 = {}; customObjectEnumerable(obj2,'a', 1, true); customObjectEnumerable(obj2, 'b', 2, true); for(let key in obj2) {console.log(obj2[key])} /* 1 2 */
function Foo() { this.name = 'foo', this.age = '18' }; Foo.prototype.geAge = function() { console.log(this.name) }; function Bar() { this.name = 'bar'; }; Bar.prototype = new Foo(); Bar.prototype.constructor = Bar; // 修正Bar.prototype.constructor 指向它自己 // 实例化Bar let myBar = new Bar(); 'name' in myBar // true myBar.hasOwnProperty('name'); // true myBar.hasOwnProperty('age'); // false
Object的defineProperty
和defineProperties
这两个方法在js中的重要性十分重要,主要功能就是用来定义或修改这些内部属性,与之相对应的getOwnPropertyDescriptor
和getOwnPropertyDescriptors
就是获取这行内部属性的描述。
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
该方法容许精确添加或修改对象的属性。经过赋值来添加的普通属性会建立在属性枚举期间显示的属性(for...in 或 Object.keys 方法), 这些值能够被改变,也能够被删除。这种方法容许这些额外的细节从默认值改变。默认状况下,使用Object.defineProperty()添加的属性值是不可变的。
对象里目前存在的 属性描述符有两种主要形式:数据描述符
和存取描述符
。
描述符必须是这两种形式之一
;不能同时是二者
。
若是一个描述符同时设置了value,writable,get和set关键字,那么它将被认为是一个数据描述符。若是一个描述符同时有value或writable和get或set关键字,将会产生一个异常。
数据描述符
和存取描述符
均具备 如下可选键值:
configurable
当且仅当该属性的 configurable 为 true 时,该属性描述符才可以被改变,同时该属性也能从对应的对象上被删除。默认为 false。
enumerable
当且仅当该属性的enumerable为true时,该属性才可以出如今对象的枚举属性中。默认为 false。
数据描述符
同时具备如下可选键值:
value
该属性对应的值。能够是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable
当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
存取描述符
同时具备如下可选键值:
get
一个给属性提供 getter 的方法,若是没有 getter 则为 undefined。该方法返回值被用做属性值。默认为 undefined。
set
一个给属性提供 setter 的方法,若是没有 setter 则为 undefined。该方法将接受惟一参数,并将该参数的新值分配给该属性。默认为 undefined。
语法
Object.defineProperty(obj, prop, descriptor)
参数
obj 要在其上定义属性的对象。
prop 要定义或修改的属性的名称。
descriptor 将被定义或修改的属性描述符。
返回值
被传递给函数的对象。
若是对象中不存在指定的属性,Object.defineProperty()就建立这个属性。当描述符中省略某些字段时,这些字段将使用它们的默认值。拥有布尔值的字段的默认值都是false。value,get和set字段的默认值为undefined。一个没有get/set/value/writable定义的属性被称为“通用的”,并被“键入”为一个数据描述符。
var o = {}; // 建立一个新对象 // 在对象中添加一个属性与数据描述符的示例 Object.defineProperty(o, "a", { value : 37, writable : true, enumerable : true, configurable : true }); // 对象o拥有了属性a,值为37 // 在对象中添加一个属性与存取描述符的示例 var bValue; Object.defineProperty(o, "b", { get : function(){ return bValue; }, set : function(newValue){ bValue = newValue; }, enumerable : true, configurable : true }); o.b = 38; // 对象o拥有了属性b,值为38 // o.b的值如今老是与bValue相同,除非从新定义o.b // 数据描述符和存取描述符不能混合使用 Object.defineProperty(o, "conflict", { value: 0x9f91102, get: function() { return 0xdeadbeef; } }); // throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors
当writable属性设置为false时,该属性被称为“不可写”。它不能被从新分配。
var o = {}; // Creates a new object Object.defineProperty(o, 'a', { value: 37, writable: false }); console.log(o.a); // logs 37 o.a = 25; // No error thrown console.log(o.a); // logs 37. The assignment didn't work.
enumerable定义了对象的属性是否能够在 for...in 循环和 Object.keys() 中被枚举。
var o = {}; Object.defineProperty(o, "a", { value : 1, enumerable:true }); Object.defineProperty(o, "b", { value : 2, enumerable:false }); Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false o.d = 4; // 若是使用直接赋值的方式建立对象的属性,则这个属性的enumerable为true for (var i in o) { console.log(i); } // 打印 'a' 和 'd' (in undefined order) Object.keys(o); // ["a", "d"] o.propertyIsEnumerable('a'); // true o.propertyIsEnumerable('b'); // false o.propertyIsEnumerable('c'); // false o.propertyIsEnumerable('d'); // true
configurable特性表示对象的属性是否能够被删除,以及除writable特性外的其余特性是否能够被修改。
var o = {}; Object.defineProperty(o, "a", { get : function(){return 1;}, configurable : false } ); // throws a TypeError Object.defineProperty(o, "a", {configurable : true}); // throws a TypeError Object.defineProperty(o, "a", {enumerable : true}); // throws a TypeError (set was undefined previously) Object.defineProperty(o, "a", {set : function(){}}); // throws a TypeError (even though the new get does exactly the same thing) Object.defineProperty(o, "a", {get : function(){return 1;}}); // throws a TypeError Object.defineProperty(o, "a", {value : 12}); console.log(o.a); // logs 1 delete o.a; // Nothing happens console.log(o.a); // logs 1
若是o.a的configurable属性为true,则不会抛出任何错误,而且该属性将在最后被删除
考虑特性被赋予的默认特性值很是重要,一般,使用点运算符和Object.defineProperty()为对象的属性赋值时,数据描述符中的属性默认值是不一样的,以下例所示。
var o = {}; o.a = 1; // 等同于 : Object.defineProperty(o, "a", { value : 1, writable : true, configurable : true, enumerable : true }); // 另外一方面, Object.defineProperty(o, "a", { value : 1 }); // 等同于 : Object.defineProperty(o, "a", { value : 1, writable : false, configurable : false, enumerable : false });
下面的例子展现了如何实现一个自存档对象。 当设置temperature 属性时,archive 数组会获取日志条目。
function Archiver() { var temperature = null; var archive = []; Object.defineProperty(this, 'temperature', { get: function() { console.log('get!'); return temperature; }, set: function(value) { temperature = value; archive.push({ val: temperature }); } }); this.getArchive = function() { return archive; }; } var arc = new Archiver(); arc.temperature; // 'get!' arc.temperature = 11; arc.temperature = 13; arc.getArchive(); // [{ val: 11 }, { val: 13 }]
或
var pattern = { get: function () { return 'I alway return this string,whatever you have assigned'; }, set: function () { this.myname = 'this is my name string'; } }; function TestDefineSetAndGet() { Object.defineProperty(this, 'myproperty', pattern); } var instance = new TestDefineSetAndGet(); instance.myproperty = 'test'; // 'I alway return this string,whatever you have assigned' console.log(instance.myproperty); // 'this is my name string' console.log(instance.myname);
当咱们查询存储器属性时会调用getter
方法(无参数)。这个方法返回值就是属性存取表达式返回的值。
当咱们设置存储器属性时会调用setter
方法(有参数)。这个方法修改存储器属性的值。
var obj = { num: 12, age: 13, get num1 () { return this.num }, set num1 (value) { this.num = value }, get age1 () { return this.age } } obj.num1 // 12 obj.num1 = 120 obj.num1 // 120 obj.age1 // 13 obj.age1 = 130 obj.age1 // 13
存储器属性定义为一个或者两个和属性同名的函数,这个函数定义没有使用function关键字而是使用get和set。
能够看出若是该属性只有getter方法则只能读取该属性不能设置该属性,一样若是只有setter方法就只能设置该属性,不能读取该属性,只有当二者都有时才能正常读取和设置属性。
通常状况,咱们会建立一个descriptor对象,而后传给defineProperty方法。以下:
var descriptor = { writable: false } Object.defineProperty(obj, 'key', descriptor);
这种状况是有风险的,若是descriptor的原型上面有相关特性,也会经过原型链被访问到,算入在对key的定义中。好比:
descriptor.__proto__.enumerable = true; Object.defineProperty(obj, 'key', descriptor); Object.getOwnPropertyDescriptor(obj,'key'); //返回的enumerable为true
为了不发生这样的意外状况,官方建议使用Object.freeze冻结对象,或者是使用Object.create(null)建立一个纯净的对象(不含原型)来使用。
接下来的注意点是默认值,首先咱们会想普通的赋值语句会生成怎样的描述符,如obj.key="value"
。
可使用Object.getOwnPropertyDescriptor
来返回一个属性的描述符:
obj = {}; obj.key = "value"; Object.getOwnPropertyDescriptor(obj, 'key'); /*输出 { configurable:true, enumerable:true, value:"value", writable:true, } */
这也是复合咱们预期的,经过赋值语句添加的属性,相关描述符都为true,可写可配置可枚举。可是使用defineProperty定义的属性,默认值就不是这样了
,其规则是这样的:
configurable: false enumerable: false writable: false value: undefined
因此这里仍是要注意下的,使用的时候把描述符写全,省得默认都成false了。
这个问题在不少前端面试中,会说起,是用Object.defineProperty( ),来监听数据get和set,来实现数据劫持的
var blog = { name: '文章1' }; console.log(blog.name); // 文章1
若是想要在执行console.log(blog.name)的同时,直接给 文章1 加个书名号,那要怎么处理呢?或者说要经过什么监听对象 blog的属性值。这时候Object.defineProperty( )就派上用场了,代码以下:
var blog= {} var name = ''; Object.defineProperty(blog, 'name', { set: function (value) { name = value; console.log('欢迎查看' + value); }, get: function () { return '《' + name + '》' } }) blog.name = '文章1'; // 欢迎查看文章1 console.log(blog.name); // 《文章1》
好比你想把浏览器的userAgent给改了,直接写navigator.userAgent = 'iPhoneX'.你再输出一下userAgent,发现并无修改。这是为何呢?咱们用这行代码看一下:
Object.getOwnPropertyDescriptor(window, 'navigator'); //输出 { configurable:true, enumerable:true, get:ƒ (), set:undefined }
缘由就找到了,navigator是有setter的,每次取值总会执行这个set函数来作返回。可是好消息是什么呢?configurable为true,那就意味这咱们能够经过defineProperty来修改这个属性,代码就至关简单了:
Object.defineProperty(navigator, 'userAgent', {get: function(){return 'iphoneX'}}) console.log(navigator.userAgent); //输出iphoneX
isPrototypeOf() 与 instanceof 运算符不一样。在表达式 "object instanceof AFunction"中,object 的原型链是针对 AFunction.prototype 进行检查的,而不是针对 AFunction 自己。isPrototypeOf() 方法容许你检查一个对象是否存在于另外一个对象的原型链上。
prototypeObj.isPrototypeOf(object)
object
在该对象的原型链上搜寻
Boolean,表示调用对象是否在另外一个对象的原型链上。
TypeError
若是 prototypeObj 为 undefined 或 null,会抛出 TypeError。
本示例展现了 Baz.prototype
, Bar.prototype
, Foo.prototype
和 Object.prototype
在 baz
对象的原型链上:
function Foo() {} function Bar() {} function Baz() {} Bar.prototype = Object.create(Foo.prototype); Baz.prototype = Object.create(Bar.prototype); var baz = new Baz(); console.log(Baz.prototype.isPrototypeOf(baz)); // true console.log(Bar.prototype.isPrototypeOf(baz)); // true console.log(Foo.prototype.isPrototypeOf(baz)); // true console.log(Object.prototype.isPrototypeOf(baz)); // true if (Foo.prototype.isPrototypeOf(baz)) { // do something safe } Baz.prototype.isPrototypeOf(baz) //true baz instanceof Baz //true baz instanceof Bar //true baz instanceof Foo //true baz instanceof Bar //true
var obj1 = { name: 'eeee' } var obj2 = Object.create(obj1) // isPrototypeOf()方法 Object.prototype.isPrototypeOf(obj1) // true obj1.isPrototypeOf(obj2) // true Object.prototype.isPrototypeOf(obj2) // true
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具备指定的属性
obj.hasOwnProperty(prop)
prop 要检测的属性 字符串 名称或者 Symbol。
用来判断某个对象是否含有指定的属性的 Boolean 。
全部继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法能够用来检测一个对象是否含有特定的自身属性;和 in 运算符不一样,该方法会忽略掉那些从原型链上继承到的属性。
1.判断属性是否存在
下面的例子检测了对象 o 是否含有自身属性 prop:
o = new Object(); o.prop = 'exists'; function changeO() { o.newprop = o.prop; delete o.prop; } o.hasOwnProperty('prop'); // 返回 true changeO(); o.hasOwnProperty('prop'); // 返回 false o.hasOwnProperty('newprop'); // 返回 true
2.自身属性与继承属性
下面的例子演示了 hasOwnProperty 方法对待自身属性和继承属性的区别:
o = new Object(); o.prop = 'exists'; o.hasOwnProperty('prop'); // 返回 true o.hasOwnProperty('toString'); // 返回 false o.hasOwnProperty('hasOwnProperty'); // 返回 false
3.遍历一个对象的全部自身属性
下面的例子演示了如何在遍历一个对象的全部属性时忽略掉继承属性,注意这里 for...in 循环只会遍历可枚举属性,因此不该该基于这个循环中没有不可枚举的属性而得出 hasOwnProperty 是严格限制于可枚举项目的(如同 Object.getOwnPropertyNames())。
var buz = { fog: 'stack' }; for (var name in buz) { if (buz.hasOwnProperty(name)) { alert("this is fog (" + name + ") for sure. Value: " + buz[name]); } else { alert(name); // toString or something else } }
4.使用 hasOwnProperty 做为属性名
JavaScript 并无保护 hasOwnProperty 属性名,所以某个对象是有可能存在使用这个属性名的属性,使用外部的 hasOwnProperty 得到正确的结果是须要的:
var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // 始终返回 false // 若是担忧这种状况,能够直接使用原型链上真正的 hasOwnProperty 方法 ({}).hasOwnProperty.call(foo, 'bar'); // true // 也可使用 Object 原型上的 hasOwnProperty 属性 Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
功能:方法直接在一个对象上定义一个或多个新的属性或修改现有属性,并返回该对象。
语法:
Object.defineProperties(obj, props) // obj: 将要被添加属性或修改属性的对象 // props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
var obj = new Object(); Object.defineProperties(obj, { name: { value: '张三', configurable: false, writable: true, enumerable: true }, age: { value: 18, configurable: true } }) console.log(obj.name, obj.age) // 张三, 18
与Object.defineProperty()
功能大致相同,对比一下
var obj = new Object(); Object.defineProperty(obj, 'name', { configurable: false, writable: true, enumerable: true, value: '张三' }) console.log(obj.name) //张三
功能:该方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不须要从原型链上进行查找的属性)
语法: 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: "张三" // }
功能:所指定对象的全部自身属性的描述符,若是没有任何自身属性,则返回空对象。
语法: Object.getOwnPropertyDescriptors(obj) obj: 须要查找的目标对象
var person = { name: '张三', age: 18 } var desc = Object.getOwnPropertyDescriptors(person); console.log(desc) // 结果以下图
推荐阅读:
1.深刻JS对象的遍历
2.从新认识javascript对象(一)——对象及其属性
3.从新认识javascript对象(三)——原型及原型链
4.[js中的Object.defineProperty()和defineProperties()
](https://segmentfault.com/a/11...
参考文章:
1.Object.defineProperty()
2.Object.create()
3.isPrototypeOf()
4.Object.prototype.hasOwnProperty()
5.理解defineProperty以及getter、setter
6.vue中v-model等父子组件通讯
7.JavaScript 知识点串烧——对象
8.从新认识javascript对象(三)——原型及原型链
9.教科书式的object方法