一、Object构造函数解析

  • 简介

object构造函数为给定制创建一个对象包装器。如果给定值是null或者undefined,将会返回并建立一个空对象,否者将会返回一个与给定值相对应的类型的对象。

1.调用方法

//以构造函数形式来调用
new Object([value])

tips:当以非构造函数形式被调用时,Object 等同于 new Object()。

2.参数

//str
var obj = new Object('text')
obj // [String: 'text']
obj.length //4
obj[0] // t
obj[1] //e
//Number
var obj2 = new Object(1) 
obj2 // [Number: 1]
var obj3 = new Object() 
obj3  // {}

上例得出:

1.如果value为基本数据类型String、Number、Boolean,则返回对应类型的对象。
2.如果省略了value参数,或value为null、undefined,则返回自身无任何属性的Object对象,即返回一个空对象。

console.log(obj instanceof Object);//true
console.log(obj instanceof String);//true

tips:你可以理解为类似于双性人吧


Object构造函数方法

  • Object.assign()

方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象———合并对象。
Object.assign()接受多个参数,第一个参数是目标对象,后面是源对象,assign方法将多个源对象的属性和方法都合并到了目标对象上面,如果在这个过程中出现同名的属性(方法),合并的属性(方法)会覆盖之前的同名属性(方法)。


特性

1.源对象会覆盖与目标对象的重名属性key

其实用过vue的人也许会有这种需求,就是重置data,熟悉vue的api的人会这样:

Object.assign(this.$data,this.$options.data())

2.浅拷贝

如果拷贝过来的属性的值是对象等复合属性,那么只能拷贝过来引用。

这是一个藏宝图和宝藏的故事
var obj = { a:{b:1} };
var obj2 = Object.assign({},obj);
我只拷贝了藏宝图,没有拷贝宝藏
ojb.a.b = 2;
console.log(obj2.a.b)
//2

tips:由于是浅拷贝,所以属性a(堆层)的内部有任何变化,都会在目标对象上呈现出来。


3.非对象的隐转换为对象

Object可以说是为了对象而服务的方法,但是参数不为对象的时候,会将参数默认转换成对象。

Object.assign([1,2,3,],[4,5])
//数组[1,2,3]被转换成 key 为 1,2,3的对象;
//而数组[4,5]被转换成key为1,2对象;
//所以12被覆盖
//[ 4,5,3]

  • Object.defineProperty()

    方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
    Object.defineProperty(obj, key, descriptor

  • obj - 目标对象

  • key - 要定义或修改的属性(key)名称

  • descriptor - 将被定义或修改的属性描述符。

  • 返回值:目标对象 obj

该方法允许精确添加或修改对象的属性。通过赋值来添加的普通属性会创建在属性枚举期间显示的属性(for...inObject.keys 方法), 这些值可以被改变,也可以被删除操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。")。这种方法允许这些额外的细节从默认值改变。默认情况下,使用Object.defineProperty()添加的属性值是不可变的。


descriptor 属性描述
目前对象的属性描述符有两种属性:

数据描述符

数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。

  • value

属性对应的值,可以使任意类型的值,默认为undefined

var data  = {};
Object.defineProperty(data,"keys",{value:"newKey"});
console.log( obj.keys );  //newKey;
  • writable

属性对应属性的值是否可以重写,设置为true可以被重写;设置为false,不能被重写。默认为false。

var data = {};
Object.defineProperty(data,"keys",{value:"newkey",writable:false})
data.keys = "change keys";
console.log(data.keys)
//newkey
  • enumerable

决定属性是否可枚举(是否被for in或者obj.key()遍历)

var data = {};
Object.defineProperty(data,"key1",{
   value:"key1value",
    writable:false,
    enumerable:true
});
Object.defineProperty(data,"key2",{
   value:"key2value",
   writable:false,
   enumerable:false
})
//{key1: "key1value", key2: "key2value"}
  for(let i in data){ 
      console.log(i)
  }
//key1
  • configurable

是否可以删除目标属性或是否可以再次修改属性的特性

var data = {};
//第一种情况:configurable设置为false,不能被删除。
Object.defineProperty(data,"newKey",{
    value:"hello",
    writable:false,
    enumerable:false,
    configurable:false
});
//{newKey: "hello"}
//删除属性
delete obj.newKey;
console.log( obj.newKey ); 
//hello

tips:这个属性起到两个作用:1,目标属性是否可以使用delete删除.2,目标属性是否可以再次设置特性

取存器述符

数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。

  • get

一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。

  • set

一个给属性提供setter 的方法,如果没有setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

拓展

vue实现双向绑定就是依赖Object.defineProperty这个方法,主要是监听属性值的变化,来实现视图更新,但是开发过的人会遇到对数组执行以下操作导致视图不更新的问题。

当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] =
当你修改数组的长度时,例如: vm.items.length = newLength;


其实对于Array,Object.defineProperty也是可以实现属性的描述的。

var arr = [1,2,3,4]
arr.forEach((item,index)=>{
    Object.defineProperty(arr,index,{
        set:function(val){
            console.log('set')
            item = val
        },
        get:function(val){
            console.log('get')
            return item
        }
    })
})
arr[1]; // get  2
arr[1] = 1; // set  1

既然数组是可以被监听的,那为什么vue不能检测vm.items[indexOfItem] = newValue导致的数组元素改变呢,哪怕这个下标所对应的元素是存在的,且被监听了的?

点击跳转:Vue为什么不能检测数组变动

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容