【前端基础进阶】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.mzph.cn/news/280156.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网页下载Google Play 的App

网页下载Google Play 的App 文章目录[点击展开](?)[] 前言 当你想在google play上下载某个应用&#xff0c;而无奈手机的系统并没有安装google servicess&#xff0c;此刻是否有些捉急&#xff1f; 本文分享的是一个网站&#xff0c;它可以无需手机而直接通过网页下载Google P…

上传jar包到nexus私服

进入maven管理页面&#xff0c;登录管理员账号 完成后可以进入对应目录下查看pom依赖 通过maven的方式depoly 在maven的conf/setting.xml 配置nexus私服的管理账号 在servers标签下添加server <server><id>nexus-snapshots</id><username>repouser<…

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

前言 经过前几篇的介绍&#xff0c;对RxJava对模式有了一定的理解&#xff1a;由Observable发起事件&#xff0c;经过中间的处理后由Observer消费。&#xff08;对RxJava还不了解的可以出门左拐&#xff09;之前的代码中&#xff0c;事件的发起和消费都是在同一个线程中执行&am…

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…

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;在开始菜单 设定好任务计划程…

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;我们…

.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;在本地可以…

Burpsuite学习(4)

2019独角兽企业重金招聘Python工程师标准>>> burpsuite spider模块通过跟踪 HTML 和 JavaScript 以及提交的表单中的超链接来映射目标应用程序&#xff0c;它还使用了一些其他的线索&#xff0c;如目录列表&#xff0c;资源类型的注释&#xff0c;以及 robots.txt 文…

Git删除分支/恢复分支

这是https://www.cnblogs.com/utank/p/7880441.html的方法&#xff0c;虽然很老现在有点不一样&#xff0c;但总体还是能用的。 总结就是两种方法 1.用commit的id恢复 2.用reflog的头指针恢复 •删除一个已被终止的分支 如果需要删除的分支不是当前正在打开的分支&#xff0c;使…

NetCore2.0Web应用之Startup

为什么80%的码农都做不了架构师&#xff1f;>>> 作为main函数的程序启动文件UseStartup 默认就是调用我们的整个应用程序的启动文件 class Program{static void Main(string[] args){var host new WebHostBuilder().UseKestrel() // 指定WebServer为Kes…

Hadoop----hdfs的基本操作

2019独角兽企业重金招聘Python工程师标准>>> HDFS操作文件的基本命令 1.创建文件夹 $>hdfs dfs -mkdir /user/centos/hadoop 2.展示目录 $>hdfs dfs -ls -r /user/centos/hadoop 3.递归展示 $>hdfs dfs -lsr /user/centos/hadoop 4.上传文件 $&g…

03 Oracle分区表

Oracle分区表 先说句题外话… 欢迎成都天府软件园的小伙伴来面基交流经验~ 一&#xff1a;什么是分区&#xff08;Partition&#xff09;&#xff1f; 分区是将一个表或索引物理地分解为多个更小、更可管理的部分。 分区对应用透明&#xff0c;即对访问数据库的应用而言&…

windows获取本地时间_如何在Windows 8中重新获得本地登录

windows获取本地时间By default a fresh Windows 8 installation prompts you to create a synchronized cloud-enabled login. While there are distinct perks to Microsoft’s live login system, sometimes you just want to keep things simple and local. Read on as we …

如何解决高并发,秒杀问题

相信不少人会被这个问题困扰&#xff0c;分享大家一篇这样的文章&#xff0c;希望能够帮到你&#xff01; 一、秒杀业务为什么难做&#xff1f;1&#xff09;im系统&#xff0c;例如qq或者微博&#xff0c;每个人都读自己的数据&#xff08;好友列表、群列表、个人信息&#xf…

Spring原理之代理与动态代理模式总结(四)

2019独角兽企业重金招聘Python工程师标准>>> 代理模式 1&#xff0c;什么是代理模式&#xff1f; 代理模式的作用是&#xff1a;为其他对象提供一种代理以控制对这个对象的访问。2&#xff0c;代理模式有什么好处&#xff1f; 在某些情况下&#xff0c;一个客户不…

可执行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...

可执行文件添加快捷方式When you make a new shortcut in Windows, it automatically adds “- Shortcut” to the end of the shortcut’s file name. This doesn’t seem like a big deal, but they can be bothersome. Sure, you can remove the text yourself when you cre…