function inherit(p){
if(p == null) throw TypeError();
if(Object.create)
return Object.create(p);
var t = typeof p;
if(t !== "object" && t !== "function") throw TypeError();
function f(){};
f.prototype = p ;
return new f();
};

创建对象

  对象创建的三种方式:

    对象自面量、构造函数、ECMAScript5中引入的 Object.create()

    自面量的方式:

var o = {name:"wj",age:"20"};

    构造函数:

function FunctionName(){}

     Object.create()

Object.create(proto, [ propertiesObject ])
proto 一个对象,作为新创建对象的原型。
propertiesObject
可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与Object.defineProperties()的第二个参数一样)。
注意:该参数对象不能是 undefined,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。

    如果 proto 参数不是 null 或一个对象值,则抛出一个 TypeError 异常。

实例一:

//Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
} Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
}; // Rectangle - subclass
function Rectangle() {
Shape.call(this); //call super constructor.
} Rectangle.prototype = Object.create(Shape.prototype); var rect = new Rectangle(); rect instanceof Rectangle //true.
rect instanceof Shape //true. rect.move(1, 1); //Outputs, "Shape moved."

实例二: proto属性与 propertiesObject 结合使用

  

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
// 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 } });

属性的查询和设置

   查询与设置两种方式: . 或 [] 方式

   对象给属性赋值时,首先会检查原型链上是否允许赋值操作。 如果 o 继承来的x是一个只读属性,那么是不允许赋值的,严格模式下会报错。 如果允许的话,只会在原对象上添加或修改,不会去修改原型链。

案例一:通过字面方式定义属性,默认属性特性是: 可配置、可枚举、可读/可写

var person = {name:"wj"};
var o = inherit(person);
o.name = "wjj";
console.log(o.name); // wjj
console.log(person.name); //wj

案例二:defineProperty 修改 name 的特性时

var person = {name:"wj"};
Object.defineProperty(person,"name",{
writable:false
})
var sub = inherit(person);
sub.name = "wjj"; //TypeError: Cannot assign to read only property 'name' of object '#<Object>'
console.log(sub.name);
console.log(person.name);

注意:1:JavaScript中,只有在查询属性时才会体会到继承的存在,在设置属性则和继承无关,这是JavaScript的一个特性,该特性让程序员可以有选择地覆盖(override)继承的属性。

      2:属性的赋值要么失败,要么创建一个属性,要么在原始对象中设置属性。

删除属性

  delete  操作符 删除自有属性 并且是 configable:true;

  delete 操作符只能删除自有属性,而不能删除继承属性(如果要删除继承属性必须通过原型对象来删除,删除同时所有继承该原型的对象都会受到影响)

检测属性 与 枚举属性

  

存取器属性 setter getter

   基本组成  

      enumerable
      configurable
      set
      get

     注意:存取器属性不具有可写性(writeable ), 如果属性同时拥有 set、get 则其可写、可读, 如果只 “set” 可写 如果只添加了 “get” 可读;

属性的特性

  属性除了包含名字和值之外,属性还包含一些标识它们可写、可枚举、可配置的特性。在ECMAScript3无法设置这些特性,其属性都是可读可写、可枚举、可配置的根本没有提供API供修改。

在ECMAScript5中引入了 查询 和 修改这些属性的API。

   这些给库开发者带来好处是:

1 可以通过这些API给原型对象添加方法,并设置其不可枚举,这让其看起来像内置方法

2 通过API设置属性不能修改和删除。

ECMAScript5为了获取和设置这些特性,引入描述对象,而描述对象获取通过 Object.getOwnPropertyDescriptor;

根据属性类型不同,描述对象返回的内容也不一样:

  数据属性: 值 value 读\写 writeable、枚举 enumerable、可配置 configurable

  存取器属性: set*、get*、枚举 enumerable、可配置 configurable

先来了解下 getOwnPropertyDescriptor

  语法:

   /**
* Gets the own property descriptor of the specified object.
* An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype.
* @param o Object that contains the property.
* @param p Name of the property.
*/
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;

从指定对象,获取自身属性描述对象; 从名字看出来,只能返回自生的属性,而继承而来的属性则只能通过获取其原型对象了

  下面看看具体实例

var o = {name:"HD"};
Object.defineProperty(o,"age",{
configurable:true,
enumerable:true,
set:function(age){
this.age = age;
},
get:function(){
return this.age;
}
}); var oDesc_name = Object.getOwnPropertyDescriptor(o,"name"); var oDesc_age = Object.getOwnPropertyDescriptor(o,"age"); var oDesc_money = Object.getOwnPropertyDescriptor(o,"toString"); var none = Object.getOwnPropertyDescriptor(o,"none");
// { get: [Function: get],set: [Function: set],enumerable: true,configurable: true }
console.log(oDesc_age);
// { value: 'HD',writable: true,enumerable: true, configurable: true }
console.log(oDesc_name);

// undefined
console.log(oDesc_money);
// undefined
console.log(none);
 

  如果要设置或修改描述对象通过 Object.defineProperty 和 Object.defineProperties  前者是单个,后者为批量;这两个区别是后者属性是同时添加的。

先了解下 Object.defineProperty 语法

 /**
* Adds a property to an object, or modifies attributes of an existing property.
* @param o Object on which to add or modify the property. This can be a native JavaScript object (that is, a user-defined object or a built in object) or a DOM object.
* @param p The property name.
* @param attributes Descriptor for the property. It can be for a data property or an accessor property.
*/
defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
Object.defineProperty 添加或者修改自有属性,不能修改继承来的属性
 
 1 var o = {name:"HD"};
 //添加
Object.defineProperty(o,"custom",{
writable:true,
configurable:true,
enumerable:true,
value:"我是先添加的"
});
console.log(Object.getOwnPropertyDescriptor(o,"custom"));
//修改
Object.defineProperty(o,"custom",{
writable:true,
configurable:true,
enumerable:true,
value:"被修改了 这么神奇"
}); console.log(Object.getOwnPropertyDescriptor(o,"custom"));
{ value: '我是先添加的',writable: true,enumerable: true,configurable: true } { value: '被修改了 这么神奇', writable: true, enumerable: true,configurable: true }

  一种特殊情况,当属性configurable 只能从 true -> false ,当configurable为false时 除了writable可以被修改外 其它特新均不能被更改

 var o = {name:"HD"};
//添加
Object.defineProperty(o,"custom",{
writable:true,
configurable:false,
enumerable:true,
value:"我是先添加的"
});
//{ value: '我是先添加的',writable: true,enumerable: true,configurable: false }
console.log(Object.getOwnPropertyDescriptor(o,"custom"));
//修改 configurable
Object.defineProperty(o,"custom",{
writable:true,
configurable:true, //TypeError: Cannot redefine property: custom
enumerable:true,
value:"被修改了 这么神奇"
});
//修改 enumerable
Object.defineProperty(o,"custom",{
writable:true,
configurable:false,
enumerable:false,//TypeError: Cannot redefine property: custom
value:"被修改了 这么神奇"
});
//修改 writable
Object.defineProperty(o,"custom",{
writable:false,
configurable:false,
enumerable:true,
value:"被修改了 这么神奇"
}); console.log(Object.getOwnPropertyDescriptor(o,"custom")); // { value: '被修改了 这么神奇',writable: false,enumerable: true,configurable: false }
当需要一次添加或修改多个属性时,我们可能里用 defineProperties() 先来看看语法
   /**
* Adds one or more properties to an object, and/or modifies attributes of existing properties.
* @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.
* @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.
*/
defineProperties(o: any, properties: PropertyDescriptorMap): any;

  先看看下面实例:

 var now = Object.defineProperties({},{
"custom":{
writable:false,
configurable:false,
enumerable:true,
value:"被修改了 这么神奇"
},
"custom2":{
writable:false,
configurable:false,
enumerable:true,
value:"被修改了 这么神奇"
}
}); console.log(now); //{ custom: '被修改了 这么神奇', custom2: '被修改了 这么神奇' }

 在不允许创建或修改的属性来说,如果用 Object.defineProperty()和 Object.defineProperties()会抛出错误!!!!

 问题汇总:

     如果对象不可配置,可以编辑已有自有属性,但是不能添加新属性;
当属性configurable 只能从 true -> false ,当configurable为false时 除了writable可以被修改外 其它特新均不能被更改;
当属性不可配置时,数据属性 存取器属性 间不能相互转换;
当数据属性不可写时,修改其值会报错;

JavaScript 对象 - 与属性的相关知识的更多相关文章

  1. JavaScript | 对象与属性

    ———————————————————————————————————————————— 对象:JavaScript是基于原型的语言,没有Class,所以将函数作为类 - - - - - - - - ...

  2. 了解JavaScript 对象的属性操作

    提起操作, 很多人都会想到我们学习过程中最经常做的操作, 就是对数据库进行增, 删, 改, 查, 既然提到这个, 那么对于对象的属性操作也不例外, 基本上可以说也是这几个操作. JS中对象的属性标签 ...

  3. JavaScript对象之属性标签

    本文介绍一下js对象的属性标签(configurable.writable.enumerable.value.get.set)的使用. 上图的要点为: 1.Object.getOwnPropertyD ...

  4. javascript对象的属性,方法,prototype作用范围分析.

    用了javascript这么久由于没有系统学习过基础,总是拿来主义. 所以对一些基础知识还是搞不清楚很混乱. 今天自己做个小例子,希望彻底能搞清楚. 注释中对象只例子的对象本身,原型只原型继承对象的新 ...

  5. javascript对象constructor属性

    概述 返回一个指向创建了该对象原型的函数引用.需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串.对于原始值(如1,true 或 "test"),该属性为只读. ...

  6. JavaScript对象遍历属性和值

    原文链接:http://caibaojian.com/javascript-object-3.html 加入你输出来一个对象,但是苦于不知道里面有哪些属性和值,这个时候,你可以通过下面的代码来遍历这个 ...

  7. JavaScript对象之属性操作

    在js对象中,我们可以对对象属性进行操作. 上图的要点为:for-in会把原型链上的可枚举属性也列出来. 上图的要点为:可以使用逻辑运算符&&进行层层查找对象是否为undefined, ...

  8. JavaScript中JSONObject和JSONArray相关知识备忘(网络转载)

    1.json的格式,有两种: {"key": "value"} //JSONObject(对象) [{"key1": "value ...

  9. 删除要被替换的元素的所有事件处理 程序和 JavaScript 对象属性

    使用本节介绍的方法替换子节点可能会导致浏览器的内存占用问题,尤其是在 IE 中,问题更加明显.在删除带有事件处理程序或引用了其他 JavaScript 对象子树时,就有可能导致内存占用问题.假设 某个 ...

随机推荐

  1. SQL从入门到基础 - 06 限制结果集范围

    一.限制结果集行数 1. Select top 5* from T_Employee order by FSalary DESC 2. (*)检索按照工资从高到低排序检索从第六名开始一共四个人的信息: ...

  2. 服务器端操作Cookie[2]

    服务器端操作Cookie,主要注意会使用以下三个类: HttpCookie,HttpResponse,HttpRequest 关于HttpCookie: 属性 描述 例子 Domain 获取或设置与此 ...

  3. list类型for遍历

    package cn.stat.p9.map.demo; import java.util.ArrayList; public class Listfor { /** * @param args */ ...

  4. ZOJ 1633

    迭代 每个数对应前面的一个数 #include<stdio.h> #include<iostream> using namespace std; #define max 88 ...

  5. SmartQQ二维码登陆接口分析

    SmartQQ是腾讯在Web上推出的一款单纯的聊天工具,pc端与移动端都可以访问,接下来具体的分析下登陆流程. 网站:http://w.qq.com/ 工具:这个随意能够看到http数据包就可以,浏览 ...

  6. PHP获取图片颜色值,检测图片主要颜色的代码:

    <?php $i=imagecreatefromjpeg("photo3.jpg");//测试图片,自己定义一个,注意路径 for ($x=0;$x<imagesx($ ...

  7. (转载)Python装饰器学习

    转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...

  8. fontresize 移动端的手机字体 大小设置

    这段js 需要置于页面上端 也就是 需要先加载js然后加载页面 (这段js是原生js而且比较短小 基本对页面加载速度无影响) FontResize : function(maxWidth){ (fun ...

  9. 一品楼论坛www.ep6.info一品楼论坛

    一品楼论坛最新地址www.ep6.info>访问一品楼网站. 一品楼是现在比较大的信息分享平台,一品楼上网必进. 一品楼江苏版块,一品楼北京版块,一品楼怡红院,一品楼怡春院. 一品楼山东信息. ...

  10. SVN莫名出错,网上找遍无果,递归删除当前目录下所有.svn文件名

    哎,太深刻的教训. 原来以前其它目录里有.SVN目录 ,而此SVN目录COPY到真正的SVN工作目录之后,会将有用的.SVN目录覆盖. 那么一样,显然,CI,UPDATE,CO之间的命令全部异常... ...