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. HTML5 为什么这么火?

    H5是超文本语言HTML的第五次修订,是近几年来Web标准巨大的飞跃. 以往,我们在Web上还只是上网看一些基础文档,但现在,Web是一个内涵非常丰富的平台.和以前版本不同的是,HTML5并非仅仅用来 ...

  2. 如何在sqlserver建立新用户并关联相应的数据库

    我们经常需要在数据库上建立有权限的用户,该用户只能去操作某个特定的数据库(比如该用户只能去读,去写等等),那么我们应该怎么在sqlserver上设置呢?下面的步骤有点长,只要一步一步跟着设置就行 方法 ...

  3. (转)asp.net实现忘记密码找回的代码

    1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...

  4. Linux 软链接和硬链接的理解与学习

    理解前提: 首先要知道 Linux任意一个文件包含2个信息:第一个信息就是文件本身存的内容,第二个信息是文件的控制信息(读写,路径,大小等等),这2个信息是分开存储的,明白这点非常重要 理解总结: L ...

  5. 简单实用 “易忘” 的SQL 语句语法,新老皆宜

    --创建数据库 create database 数据库名 on primary ( name='数据库名_data',  filename='数据库储存路径', size=数据库初始大小(MB),   ...

  6. 近期Responsive web design项目经验分享

    关于meta   <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, user ...

  7. jQuery 幻灯片 ----摘录

    Cloud Carousel (演示 | 下载) ShineTime (演示 | 下载) Nivo Slider (演示 | 下载) Interactive Photo Desk (演示 | 下载) ...

  8. 窗口!窗口!- Windows程序设计(SDK)003

    窗口!窗口! 让编程改变世界 Change the world by program 内容节选: 在前边两节课的例子中,我们通过 MessageBox 函数创建一个消息框程序,消息框其实就是用来跟用户 ...

  9. FileInputStream

    InputStream 基类,抽象类 FileInputStream 读取文件的字节流 BufferedInputStream 缓冲输入字符流 package file; import java.io ...

  10. os8 location authorization 错误.

    今天在XCode6上打开之前写的地图时,给我报这个错 location authorization 去网上查了一番,才知道Xcode6对地图的设置稍有修改 在stackoverflow上找到了答案 i ...