Object

在看 ES6 Object的时候,我发觉ES5 Object 的更新我并不是完全知道。

于是觉得还是看一下.

1. __proto__

作为一个 半吊子前端开发人员. 居然不知道这个..

首先这个 MSDN 上的例子

function Rectangle() {
}

var rec = new Rectangle();

if (console && console.log) {
    console.log(rec.__proto__ === Rectangle.prototype);  // Returns true
    rec.__proto__ = Object.prototype;
    console.log(rec.__proto__ === Rectangle.prototype);  // Returns false
}

然后我发现。 貌似这个就是原型链。

只不过以前是隐藏的现在将他公布出来。

他指向构造函数的 prototype.

例如这样

function a() {  };
a.prototype.haha = 10;
a.prototype.haha1 = 11;

var a1 = new a();
h.w(a1.__proto__);
//constructor:a()
//haha:10
//haha1:11
//haha2:20

a1.__proto__.haha2 = 20;

h.w(a1.haha);
h.w(a1.haha1);
h.w(a1.haha2);

h.w(a1.__proto__);
//constructor:a()
//haha:10
//haha1:11
//haha2:20

这边其实是有些疑问的.

比如 haha & haha1 是并不存在于 a1.__proto__ 中.

理论上是 在 a1.__proto__ 中找不到 向上层 prototype 中寻找

但是输出的时候却看得见。

还有就是

在第一次执行 h.w(a1.__proto__); 的时候

确输出了 haha2. 这个应该是在第二次执行的输出的时候才有的啊。

于是在加了一段代码.

function a() {  };
a.prototype.haha = 10;
a.prototype.haha1 = 11;

var a1 = new a();

h.w(a1.__proto__);
h.w(a1.haha2); //undefined.

a1.__proto__.haha2 = 20;

h.w(a1.haha);
h.w(a1.haha1);
h.w(a1.haha2);

h.w(a1.__proto__);

所以我不知道 chrome 在搞什么...

但是能确定的是 __proto__ 就是原型链。

所以.

var o = {}; // o = new Object()

o.__proto__ === Object.prototype

2. Object.assign

var target = { a: 1 };

var source1 = { b: 2 };
var source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

简单说就是合并。

如果有相同的值以后面为准

首先需要注意的是,复制的问题。

多层嵌套以后,他是直接复制的.

    var target4 = {a: 1};
    var target5 = Object.assign({}, target4);

    target5.a = 2;
    h.w(target4); //1

    var target = { a: 1,b:{ b1:1 } };

    var target1 = Object.assign({},target);

    target1.a = 2;
    target1.b.b1 = 2;

    h.w(target.a); //1
    h.w(target.b.b1); //2

所以如果你想复制一个 Object

    var target = { a: 1,b:{ b1:1 } };
    var target1 = Object.assign({},target);

有多层嵌套的肯定不行。

assign 一些特殊的传入值

    try{
        Object.assign(undefined);
        Object.assign(null);
    }
    catch(ex) {
        h.w(ex.name + ":" + ex.message)
        //TypeError:Cannot convert undefined or null to object
    }

    h.w(Object.assign(2)); //Number {[[PrimitiveValue]]: 2}
    h.w(Object.assign("haha")); //String {0: "h", 1: "a", 2: "h", 3: "a", length: 4, [[PrimitiveValue]]: "haha"}
    h.w(Object.assign({a:1})); //Object {a: 1}
    h.w(Object.assign({},true)); //Object {}
    h.w(Object.assign({},"aaa","bbb")); //Object {0: "b", 1: "b", 2: "b"}
    h.w(Object.assign({},10)); //Object {}

3 Object.create

var o = Object.create({a:1}, {
        size: {
            value: "large",
            enumerable: true
        },
        shape: {
            value: "round",
            enumerable: true
        }
    });

h.w(o.a);
h.w(o.size);
h.w(o.shape);

这个是微软的例子

在我的理解已经很说明问题了。

第一个参数 就是原型链继承。

function a() {}
a.prototype = 第一个参数
return new a()

第二个参数我感觉像是 this 不过我不能100%确定..

4. defineProperty & defineProperties

Object.defineProperty(object, propertyname, descriptor)

object

必需。 要在其上添加或修改属性的对象。 这可能是一个本机 JavaScript 对象(即用户定义的对象或内置对象)或 DOM 对象。

propertyname

必需。 一个包含属性名称的字符串。

descriptor

必需。 属性描述符。 它可以针对数据属性或访问器属性。

// Create a user-defined object.
var obj = {};

// Add a data property to the object.
Object.defineProperty(obj, "newDataProperty", {
    value: 101,
    writable: true,
    enumerable: true,
    configurable: true
});

// Set the property value.
obj.newDataProperty = 102;
document.write("Property value: " + obj.newDataProperty + newLine);

value 默认值

writable 是否可写

enumerable 可枚举

configurable 是否可删除

set 写的接口

get 读的接口

大概就这些。

但是里面还是有不少东西值得注意

    var obj = {};

    // Add a data property to the object.
    Object.defineProperty(obj, "newDataProperty", {
        value: 101
    });

    obj.newDataProperty = 100;
    h.w(obj.newDataProperty); //101

比如加上 value 这个默认值, 似乎就会加上 writable = false

修改不了,除非你显示声明了 writable = true

configurable 也就是说 delete obj.newDataProperty

不会再有效了。

enumerable .

    var obj1 = { a:1 };

    // Add a data property to the object.
    Object.defineProperty(obj1, "newDataProperty", {
        value: 101,
        enumerable:false
    });

    for(var key in obj1)
        h.w(key);

set,get

这个比较简单。 就是提供了一个方法而已.

Object.defineProperty(obj, "newAccessorProperty", {
    set: function (x) {
        document.write("in property set accessor" + newLine);
        this.newaccpropvalue = x;
    },
    get: function () {
        document.write("in property get accessor" + newLine);
        return this.newaccpropvalue;
    },
    enumerable: true,
    configurable: true
});

最后 defineProperties

就是多一层 嵌套。 可以一次写多个。

var obj = {};
Object.defineProperties(obj, {
    newDataProperty: {
        value: 101,
        writable: true,
        enumerable: true,
        configurable: true
    },
    newAccessorProperty: {
        set: function (x) {
            document.write("in property set accessor" + newLine);
            this.newaccpropvalue = x;
        },
        get: function () {
            document.write("in property get accessor" + newLine);
            return this.newaccpropvalue;
        },
        enumerable: true,
        configurable: true
    }});

也可以生成好以后 传进去

var obj = {};

var descriptors = { xxx : {value:1 }};

Object.defineProperties(obj, descriptors)

5. Object.freeze(object)

冻结。

其实也就是通过 defineProperty 将除了 enumerable 所有属性设置为false.

6.getOwnPropertyDescriptor && getOwnPropertyDescriptors

    var o = { a:1 };
    var keys = Object.getOwnPropertyDescriptor(o,"a");

    h.w(keys);

    configurable:true
    enumerable:true
    value:1
    writable:true

    Object.freeze(o);
    var keys1 = Object.getOwnPropertyDescriptor(o,"a");

    h.w(keys1);

    configurable:false
    enumerable:true
    value:1
    writable:false

其实就是返回某一个字段 属性。

然后你可以修改了以后 再赋给 字段...

所以说。 给 object 增加了 属性 也不是绝对的安全啊 哈哈哈

getOwnPropertyDescriptors 是ES7的提案。

可以一次返回所有 不用一个一个字段来弄.

7. getOwnPropertyNames

function Pasta(grain, width, shape) {
    // Define properties.
    this.grain = grain;
    this.width = width;
    this.shape = shape;
    this.toString = function () {
        return (this.grain + ", " + this.width + ", " + this.shape);
    }
}

Pasta.prototype.test = "haha";

// Create an object.
var spaghetti = new Pasta("wheat", 0.2, "circle");

// Get the own property names.
var arr = Object.getOwnPropertyNames(spaghetti);
document.write (arr);

// Output:
//   grain,width,shape,toString

上面这个是微软的例子。 就是遍历 属性

很简单,但是他很好玩的是

var o = { a:1 }

Object.defineProperty(o,'haha',{
    enumerable:false,
    value:2
});

var arr1 = Object.getOwnPropertyNames(o);
h.w(arr1);

他无视了 enumerable

8. getPrototypeOf 获取原型链


    var a = function() {}

    h.w(a.prototype == Object.getPrototypeOf(a)); //false

    var b = new a();

    h.w(b.__proto__ == Object.getPrototypeOf(b)) //true

9. Object.is


主要是用来规避

    h.w(+0 === -0);  //true
    h.w(NaN === NaN); //false

    h.w(Object.is(+0,-0)); //false
    h.w(Object.is(NaN,NaN)); //true

其他一样

10. isExtensible isSealed isFrozen


https://msdn.microsoft.com/zh-cn/library/ff806189(v=vs.94).aspx

https://msdn.microsoft.com/zh-cn/library/ff806185(v=vs.94).aspx

https://msdn.microsoft.com/zh-cn/library/ff806188(v=vs.94).aspx

这三个真的木有什么好讲的..

Object.preventExtensions 设置不可扩展

Object.seal 设置是否 configurable

标题三个 就是来检测是否设置了。

11.Object.Keys


感觉和 getOwnPropertyNames 一模一样.

只不过

var o = { a:1 }

Object.defineProperty(o,'haha',{
    enumerable:false,
    value:2
});

h.w(Object.keys(o))

enumerable 有用了

资料

ES5手册

ES5规范之Object增强

09 Object的更多相关文章

  1. Java多线程系列 基础篇09 Object.wait/notifyJVM源码实现

    转载 https://www.jianshu.com/p/f4454164c017 作者 占小狼 最简单的东西,往往包含了最复杂的实现,因为需要为上层的存在提供一个稳定的基础,Object作为java ...

  2. js中类型识别的方法

    第一种方法typeof typeof是一种运算符,它的值有以下几种 <!DOCTYPE html> <html lang="en"> <head> ...

  3. ES6入门笔记

    ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...

  4. 泛型中? super T和? extends T的区别

    原文出处: 并发编程网 经常发现有List<? super T>.Set<? extends T>的声明,是什么意思呢?<? super T>表示包括T在内的任何T ...

  5. Spring如何处理线程并发

    Spring如何处理线程并发   我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度.这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突.我 ...

  6. Unity3D之Assetbundle

    原地址: Unity3D之Assetbundle 有几个地方需要注意下 1.如何解决资源重复加载的问题 2.初始化了就直接出现在场景中了  感觉怪怪的 3.标红的地方要注意下  prefab上挂载的脚 ...

  7. 030 RDD Join中宽依赖与窄依赖的判断

    1.规律 如果JoinAPI之前被调用的RDD API是宽依赖(存在shuffle), 而且两个join的RDD的分区数量一致,join结果的rdd分区数量也一样,这个时候join api是窄依赖 除 ...

  8. 029 RDD Join相关API,以及程序

    1.数据集 A表数据: 1 a 2 b 3 c B表数据: 1 aa1 1 aa2 2 bb1 2 bb2 2 bb3 4 dd1 2.join的分类 inner join left outer jo ...

  9. Knowing how all your components work together: distributed tracing with Zipkin

    转自: http://aredko.blogspot.com/2014/02/knowing-how-all-your-components-work.html In today's post we ...

随机推荐

  1. Linux From Scratch(从零开始构建Linux系统,简称LFS)- Version 7.7(一)

    一. 准备工作 1. 需要一个Linux宿主系统,例如早先版本的 LFS,Ubuntu/Fedora,SuSE 或者是在你的架构上可以运行的其它发行版 如果想实现Win7与Linux双系统,可参考我的 ...

  2. linux中档案类型

    我们用ls-l命令时,在第一列的第一个字符表示是档案类型.如: 那d和-等这些都表示什么呢? [ d ]-------目录 [ - ]--------文件 [ l ]---------连结档(link ...

  3. Win Server 2008 RD案例:Client通过Server的浏览器上网

    一.简介 RD是Windows Server远程桌面服务,可以实现从客户端运行服务器上的软件.首先在Server安装软件,设置能远程访问的应用和账号,并且创建.rdp快捷方式文件,然后Client打开 ...

  4. Nginx负载均衡配置说明

    WEB服务做负载均衡的方法有很多种,但使用Nginx做负载均衡部署毫无疑问是非常高效也是非常流行的一种. 本人大多数做.NET开发,但部署负载却一直用Nginx,对其他的负载方式研究不多,只测试过一次 ...

  5. MySQL server has gone away报错原因分析/

    在平时和开发的交流 以及 在论坛回答问题的或称中会发现这个问题被问及的频率非常高. 程序中报错: MySQL server has gone away 是什么意思? 如何避免? 因此,感觉有必要总结一 ...

  6. Nodejs以后台服务启动

    1: 从网上查找  LINUX中我们可以使用这种简单的方式让node.js在后台运行: nohup node your_app.js & 经多次实验一直没有成功   2:使用 forever ...

  7. C#创建委托实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyDe ...

  8. Linux下管道编程

    功能: 父进程创建一个子进程父进程负责读用户终端输入,并写入管道 子进程从管道接收字符流写入另一个文件 代码: #include <stdio.h> #include <unistd ...

  9. Vijos1006P1006晴天小猪历险记之Hill[最短路]

    P1006晴天小猪历险记之Hill Accepted 标签:晴天小猪历险记[显示标签]     背景 在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结……不过有一 ...

  10. ThreadLocal实现方式&使用介绍—无锁化线程封闭

    原文出处: xieyu_zy 虽然现在可以说很多程序员会用ThreadLocal,但是我相信大多数程序员还不知道ThreadLocal,而使用ThreadLocal的程序员大多只是知道其然而不知其所以 ...