1、创建对象

(1)、通过对象直接量的方式创建
说明:对象直接量是由若干名/值对组成的映射表,名/值对中间用冒号分隔,名/值对之间用逗号分隔,整个映射表用花括号括起来。
如:

 
 
 
5
5
 
 
 
 
 
1
var empty = {}; //创建一个空对象
2
var point = {
3
    x : 0,
4
    y : "ccc
5
}
 
 
对象直接量是一个表达式,每次运算都会创建并初始化一个新的对象。
(2)、通过new创建对象
new运算符创建并初始化一个新对象。关键字new后跟随一个函数调用。这里的函数称作构造函数(constructor),构造函数用于初始化一个新创建的对象。
如:

 
 
 
1
1
 
 
 
 
 
1
var o = new Object();     //创建一个空对象
 
 
(3)、Object.create()
它创建一个新对象,其中第一个参数是这个对象的原型,第二个为可选参数,用以对对象的属性进一步描述。
它是一个静态函数,而不是提供给某个对象调用的方法。
如:

 
 
 
2
2
 
 
 
 
 
1
var o = Object.create({ x: 1, y: 2});     //o继承了属性x和y
2
var o2 = Object.create(Object.prototype);    //创建一个空对象
 
 
2、属性的查询和设置
当通过[]来访问对象的属性时,属性名通过字符串来表示。
使用[]运算符访问时,字符串值是动态的,可以在运行时更改。
使用 . 运算符访问时,后接的是标识符,标识符是静态的,写死在程序中。
不同的场景可以使用不同的运算符来进行访问。
(1)继承
对属性赋值操作时首先要检查原型链,以此判定是否允许赋值。
如果一个对象继承自另一个对象的一个自读属性,那么赋值操作是不允许的。
如果允许属性赋值操作,它总是在原始对象上创建属性或对已有的属性赋值,而不会去修改原型链。

 
 
 
6
6
 
 
 
 
 
1
//这里使用es5 的Object.create()函数来创建对象
2
var o = {r: 1};    //一个用来继承的对象
3
var c = Object.create(o);     //创建一个新对象c,c继承o对象属性r
4
c.x = 1; c.y = 2;     //c定义两个属性
5
c.r = 2;     //c覆盖继承来的属性
6
console.log(o.r);    //1 原型对象没有修改
 
 
(2)、属性访问错误
在一下这些场景下给对象o设置属性p会失败:
  • o中的属性p是只读的:不能给只读属性重新赋值(defineProperty()方法中有一个例外,可以对可配置的只读属性重新赋值)。
  • o中的属性p是继承属性,且它是只读的:不能通过同名自有属性覆盖只读的继承属性。
  • o中不存在自有属性p:o没有使用setter方法继承属性p,并且o的可扩展性是false。如果o中不存在p,而且没有setter方法可供调用,则p一定会添加至o中。但如果o不是可扩展的,那么在o中不能定义新属性。

3、删除属性

通过delete运算符可以删除对象的属性。
delete运算符只能删除自有属性,不能删除继承属性。(要删除继承属性必须从定义这个属性的原型对象上删除它,而且这会影响到所有继承自这个原型的对象)。
delete不能删除那些可配置性为false的属性。(尽管可以删除不可扩展对象的可配置属性)

 
 
 
6
6
 
 
 
 
 
1
o = {x:1};
2
delete o.x;    //true
3
delete o.x;     //什么也没做(x已经不存在),返回true
4
delete o.toString;     //什么也没做(toString是继承来的) ,返回true
5
delete 1;     //无意义,返回true
6
delete Object.prototype;     //不能删除,属性是不可配置的
 
 
4、检测属性
(1)、in运算符
用于检测一个对象是否包含某个属性,如果对象的自有属性或继承属性中包含这个属性则返回true。
如:

 
 
 
4
4
 
 
 
 
 
1
var o = { x:1 };
2
"x" in o;     //true "x"是o的属性
3
"y" in o;    //false    "y"不是o的属性
4
"toString" in o;     //true o继承toString属性
 
 
(2)、hasOwnProperty()方法
用来检测给定的名字是否是对象的自有属性,对于继承属性它将返回false。
如:

 
 
 
4
4
 
 
 
 
 
1
var o = { x:1 };
2
o.hasOwnProperty("x");    //true o有一个自有属性x
3
o.hasOwnProperty("y");    //false o中不存在属性y
4
o.hasOwnProperty("toString");    //false toString是继承属性
 
 
(3)、propertyIsEnumerable()方法
它用来检测是自有属性且这个属性的可枚举性为true时它才返回true。
某些内置属性是不可枚举的,通常由javascript代码创建的属性都是可枚举的。如

 
 
 
5
5
 
 
 
 
 
1
var o = Object.create({ y: 2});
2
o.x = 1;
3
o.propertyIsEnumerable("x");    // true: o有一个可枚举的自有属性x
4
o.propertyIsEnumerable("y");    //false y是继承来的
5
Object.prototype.propertyIsEnumerable("toString");    //false 不可枚举
 
 
(4)、判断一个属性是否是undefined
使用 “ !== ”,如

 
 
 
8
8
 
 
 
 
 
1
var o = { x:1 };
2
o.x !== undefined;     //true o中有属性x
3
o.y !== undefined;     //false o中没有属性y
4
o.toString !== undefined;     //true o继承了toString属性
5
o.z = undefined;
6
o.z !== undefined;     //false 属性存在,但值为undefined
7
delete o.z;    //删除属性
8
"z" in o;    //false,属性不存在
 
 
5、属性getter和setter
在es5中,属性值可以用一个或两个方法代替,这个两个方法是getter和setter。由getter和setter定义的属性称做“存取器属性”。
存取器属性不具有可写性。如果属性同时具有getter和setter方法,那么它是一个读/写属性,如果只有getter方法,那么它是一个只读属性,如果它只有setter方法,那么它只有一个只写属性(数据属性中有一些例外)
getter方法:无参数,返回值是属性存取表达式的值。
setter方法:一个参数,设置属性值,
语法:

 
 
 
6
6
 
 
 
 
 
1
var o = {
2
    data_prop: value,    //普通的数据属性
3
    //存取器属性
4
    get accessor_prop() { /*函数体 */ },
5
    set accessor_prop() { /*函数体 */ }
6
};
 
 
存取器属性是可以继承的,如

 
 
 
21
21
 
 
 
 
 
1
//笛卡尔点坐标对象
2
var p = {
3
x: 1.0,
4
y: 1.0,
5
get r() {
6
return Math.sqrt(this.x * this.x + this.y * this.y);    //this指代这个点的对象,即p
7
},
8
set r(newvalue) {
9
var oldvalue = Math.sqrt(this.x * this.x + this.y * this.y);
10
var ratio = newvalue / oldvalue;
11
this.x *= ratio;
12
this.y *= ratio;
13
},
14
get theta() {
15
return Math.atan2(this.y, this.x);
16
}
17
};
18
var q = Object.create(p);     //创建一个继承getter和setter的新对象
19
q.x = 2, q.y = 1;        //给q添加两个属性
20
console.log(q.r);     //可以使用继承的存取器属性
21
console.log(q.theta);
 
 
6、属性的特性
数据属性包含4个特性,分别是它的值(value)、可写性(writable)、可枚举性(enumerable)、可配置性(configurable)。存取器属性不具有值特性和可写性,它们的可写性是由setter方法存在与否决定的。因此存取器属性的4个特性是读取(get)、写入(set)、可枚举性和可配置性。
通过调用Object.getOwnPropertyDescriptor()可以获得某个对象特定属性的属性描述符(即代表4个特性)。

 
 
 
16
16
 
 
 
 
 
1
console.log(Object.getOwnPropertyDescriptor({
2
    x: 1
3
}, "x"));     //返回 {value:1, writable:true, enumerable:true, configurable:true}
4

5
var random = {
6
    get octet() {
7
        return Math.floor(Math.random() * 256);
8
    },
9
}
10
//查询定义的random对象的octet属性
11
console.log(Object.getOwnPropertyDescriptor(random, "octet")); 
12
//返回 {get: /*function函数*/, set:undefined, enumerable:true, configurable:true}
13

14
//对于继承属性和不存在的属性,返回undefined
15
console.log(Object.getOwnPropertyDescriptor({}, "x"));    //undefined
16
console.log(Object.getOwnPropertyDescriptor({}, "toString"));    //undefined
 
 
设置属性的特性,或者让新建属性具有某种特性,则需要调用Object.definePeoperty(),传入需要修改的对象、要创建或修改的属性的名称以及属性描述符对象

 
 
x

30
 
 
 
 
 
1
var o = {};     //创建一个空对象
2
//添加一个不可枚举的数据属性x,并赋值为1
3
Object.defineProperty(o, "x", {
4
    value: 1,
5
    writable: true,
6
    enumerable: false,
7
    configurable: true
8
});
9
console.log(o.x); //1
10
console.log(Object.keys(o)); //返回[]  keys方法,返回所有可枚举的属性 
11
//对属性x进行修改,让它变为只读
12
Object.defineProperty(o, "x", {
13
    writable: false
14
});
15
o.x = 2; //更改属性值
16
console.log(o.x);    //1 没有被更改,属性是只读
17

18
//属性是可配置的,因此可以通过这种方式对它进行修改
19
Object.defineProperty(o, "x", {
20
    value: 2
21
});
22
console.log(o.x);    // 2
23
//将x从数据属性修改为存取器属性
24
Object.defineProperty(o, "x", {
25
    get: function() {
26
        return 0;
27
    }
28
});
29
console.log(o.x);     // 0
30
console.log(Object.getOwnPropertyDescriptor(o, "x"));     //查看x的特性
 
 
如果需要同时修改或创建多个属性,并设置属性描述符,则需要使用Object.defineProperties()。参数一为该对象,参数二为一个映射表。如:

 
 
 
22
22
 
 
 
 
 
1
//首先创建一个空对象,然后给它添加两个数据属性和一个只读存取器属性。
2
var p = Object.defineProperties({}, {
3
    x: {
4
        value: 1,
5
        writable: true,
6
        enumerable: true,
7
        configurable: true
8
    },
9
    y: {
10
        value: 1,
11
        writable: true,
12
        enumerable: true,
13
        configurable: true
14
    },
15
    r: {
16
        get: function() {
17
            return Math.sqrt(this.x * this.x + this.y * this.y)
18
        },
19
        enumerable: true,
20
        configurable: true
21
    }
22
});
 
 
规则:
  • 如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给它添加新属性。
  • 如果属性是不可配置的,则不能修改它的可配置性和可枚举性。
  • 如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将它转换为数据属性。
  • 如果数据属性是不可配置的,则不能将它转换为存取器属性。
  • 如果数据属性是不可配置的,则不能将它的可写性从false修改为true,但可以从true修改为false。
  • 如果数据属性是不可配置且不可写的,则不能修改它的值。然而可配置但不可写属性的值是可以修改的(实际上是先将它标记为可写,然后修改它的值,最后转换为不可写的)。

例子:复制属性的特性

 
 
 
21
21
 
 
 
 
 
1
/*
2
    *给Object.prototype添加一个不可枚举的extend()方法
3
    这个方法继承自调用它的对象,将作为参数传入的对象的属性一一复制
4
    除了值之外,也复制属性的所有特性,除非在目标对象中存在同名的属性
5
    参数对象的所有自有对象(包括不可枚举的属性)也会一一复制
6
*/
7
Object.defineProperty(Object.prototype, "extend", {
8
    writable: true,
9
    enumerable: false,     //不可枚举
10
    configurable: true,
11
    value: function(o) {
12
        var names = Object.getOwnPropertyNames(o);     //得到所有的自有属性,包括不可枚举属性
13
        for (var i = 0; i < names.length; i++) {
14
            if (names[i] in this) {        //如果属性已经存在,则跳过
15
                continue;
16
            }
17
            var desc = Object.getOwnPropertyDescriptor(o, names[i]); //获取o中的属性描述符
18
            Object.defineProperty(this, names[i], desc);    //用它给当前对象(this)创建一个属性
19
        }
20
    }
21
});
 
 
7、对象的三个属性
(1)原型属性
原型属性是在实例对象创建之初就设置好的。
通过Object.getPrototypeOf()方法可以查询某个对象的原型
如:

 
 
 
7
7
 
 
 
 
 
1
function People() {}     //空的构造函数
2
People.prototype = {     //设置原型属性
3
    constructor: People,
4
    name: "cart",
5
}
6
var cc = new People();    //实例化构造函数,创建一个新的对象
7
console.log(Object.getPrototypeOf(cc));
 
 
检测一个对象是否是另一个对象的原型,用isPrototypeOf()方法

 
 
 
7
7
 
 
 
 
 
1
//定义一个原型对象
2
var p = {
3
    x: 1
4
};
5
var o = Object.create(p);     //使用原型对象创建一个对象
6
console.log(p.isPrototypeOf(o));     // true
7
console.log(Object.prototype.isPrototypeOf(o));     //true o继承p,p继承Object.prototype
 
 
(2)类属性
对象的类属性是一个字符串,用以表示对象的类型信息。
通过toString()方法可以间接的查询到这个对象的类属性。返回如下格式的字符串:
[ object class ]
因此,要想获得对象的类,可以调用对象的toString()方法,然后提取已返回字符串的第8个到倒数第二个位置之间的字符。

 
 
 
13
13
 
 
 
 
 
1
// 定义一个获取对象类属性的函数
2
function classof(o) {
3
    if (o === null) {
4
        return "Null";
5
    }
6
    if (o === undefined) {
7
        return "Undefined";
8
    }
9
    return Object.prototype.toString.call(o).slice(8, -1); //间接调用toString方法返回类属性
10
}
11
classof(1);     // NUmber
12
function f() {};     //定于一个自定义构造函数
13
classof(new f());     // Object
 
 
(3)、可扩展性
  • 对象的可扩展性用以表示是否可以给对象添加新属性。可以通过将对象传入Object.isExtensible(),来判断该对象是否是可扩展的。
  • 如果想将对象转换为不可扩展的,需要调用Object.preventExtensions(),将待转换的对象作为参数传进去。
对象一旦转换为不可扩展,就无法再将其转换为可扩展的。给一个不可扩展的对象的原型添加属性,这个不可扩展的对象同样会继承这些新属性。

 
 
9
9
 
 
 
 
 
1
var o = {
2
    x: 1,
3
    y: {
4
        z: [false, null, ""]
5
    }
6
};
7
console.log(Object.isExtensible(o));    //true
8
Object.preventExtensions(o);    //将对象转换为不可扩展
9
console.log(Object.isExtensible(o));    //false
 
 
  • Object.seal(Object);它除了可以设置对象的不可扩展,还可以设置对象的自有属性都设置为不可配置的,不能删除和配置。对于它已经有的可写属性依然可以设置。
  • Object.isSealed(Object); 检查对象是否封闭。
  • Object.freeze();更严格的锁定对象(冻结)。除了将对象设置为不可扩展,属性设置为不可配置,所有的自有属性设置为只读的,(如果对象存储器属性有setter方法,存储器属性不受影响,依然可以通过属性赋值给他们)。
  • Object.isFrozen() 来检测对象是否冻结。
8、序列化对象
对象序列化(serialization)是指将对象的状态转换为字符串,也可以将字符串还原为对象。
使用函数JSON.stringify()和JSON.parse()用来序列化和还原javascript对象。

 
 
 
11
 
 
 
 
 
1
// 定义一个测试对象
2
var o = {
3
    x: 1,
4
    y: {
5
        z: [false, null, ""]
6
    }
7
};
8
var s = JSON.stringify(o);
9
var p = JSON.parse(s);
10
console.log(s);    //解析为json格式字符串 {"x":1,"y":{"z":[false,null,""]}}
11
console.log(p);    //将字符串转换为javascript对象
 
 
函数、RegExp、Error对象和undefined值不能序列化和还原。JSON.stringify()只能序列化对象可枚举的自有属性。
 
 

span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }.cm-searching {background: #ffa; background: rgba(255, 255, 0, .4);}.cm-force-border { padding-right: .1px; }@media print { .CodeMirror div.CodeMirror-cursors {visibility: hidden;}}.cm-tab-wrap-hack:after { content: ""; }span.CodeMirror-selectedtext { background: none; }.CodeMirror-activeline-background, .CodeMirror-selected {transition: visibility 0ms 100ms;}.CodeMirror-blur .CodeMirror-activeline-background, .CodeMirror-blur .CodeMirror-selected {visibility:hidden;}.CodeMirror-blur .CodeMirror-matchingbracket {color:inherit !important;outline:none !important;text-decoration:none !important;}.CodeMirror-sizer {min-height:auto !important;}
-->

li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list-style-type:lower-latin;}.wiz-editor-body ol.wiz-list-level3 > li {list-style-type:lower-roman;}.wiz-editor-body blockquote {padding: 0 12px;}.wiz-editor-body blockquote > :first-child {margin-top:0;}.wiz-editor-body blockquote > :last-child {margin-bottom:0;}.wiz-editor-body img {border:0;max-width:100%;height:auto !important;margin:2px 0;}.wiz-editor-body table {border-collapse:collapse;border:1px solid #bbbbbb;}.wiz-editor-body td,.wiz-editor-body th {padding:4px 8px;border-collapse:collapse;border:1px solid #bbbbbb;min-height:28px;word-break:break-word;box-sizing: border-box;}.wiz-hide {display:none !important;}
-->

js权威指南学习笔记(四)对象的更多相关文章

  1. js权威指南---学习笔记02

    1.JS只有函数作用域,没有块级作用域这个概念: 它有一个特性——声明提前:在同一个函数中不同位置声明的变量,都被提前在函数开始的时候,执行声明操作:在原先位置执行赋值操作: 2.声明的全局变量,相当 ...

  2. js权威指南学习笔记(一)类型、值和变量

    1.数据类型:原始类型(primitive type) 和对象类型(object type) 原始类型包括数字.字符串和布尔值: 除数字.字符串.布尔值.null(空).undefined(未定义), ...

  3. js权威指南---学习笔记01

    1.当函数赋值给对象的属性时,就变为了方法:2.被零整除不报错,只会返回无穷大(Infinity)或者负无穷大.例外:零除以零等于非数字(NaN).3.NaN与任何值都不相等! 4.Javascrip ...

  4. js权威指南学习笔记(三)语句

    1.声明语句 如果用var声明的变量没有初始化,那么这个变量的值会被初始化为undefined. 函数声明语句的语法如下:       4 4           1 console.log(func ...

  5. js权威指南学习笔记(二)表达式与运算符

    1.数组初始化表达式 数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充undefined.如:       2 2           1 var arr = [1,,,,,6]; 2 ...

  6. netty权威指南学习笔记四——TCP粘包/拆包之粘包问题解决

    发生了粘包,我们需要将其清晰的进行拆包处理,这里采用LineBasedFrameDecoder来解决 LineBasedFrameDecoder的工作原理是它依次遍历ByteBuf中的可读字节,判断看 ...

  7. IDA Pro 权威指南学习笔记(四) - IDA 用户界面的基本规则

    基本规则: IDA 不提供撤销功能 如果由于不小心按下某个键,导致数据库文件发生意外,这时需要将显示窗口恢复到以前的状态 几乎所有的操作都有其对应的菜单项.热键和工具栏按钮 IDA 的工具栏高度可配置 ...

  8. JavaScript 权威指南-学习笔记(一)

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! ## JavaScript 权威指南-学 ...

  9. HTTP权威指南-学习笔记

    目录 HTTP权威指南-学习笔记 HTTP: Web的基础 URL与资源 HTTP报文 连接管理 HTTP结构 Web服务器 代理 缓存 集成点: 网关,隧道及中继 Web机器人 识别,认证与安全 客 ...

随机推荐

  1. C#-★★函数★★

    一个较大的程序一般应分为若干个程序块,每一个模块用来实现一个特定的功能.所有的高级语言中都有子程序这个概念,用子程序来实现模块的功能.在C#语言中,子程序的作用是由一个主函数和若干个函数构成.由主函数 ...

  2. Doc/Docx/PDF to Html

    TODO 判断源文件是否有格式??

  3. fastdfs-client-java操作fastdfs

    一.在https://github.com/happyfish100/fastdfs-client-java 下载客户端,解压后并执行ant命令,在E:\tools\libs\fastdfs\fast ...

  4. [蓝桥杯][2016年第七届真题]路径之谜(dfs)

    题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡. 城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格.[如图1.png]所示. 按习俗,骑士要从西北角走到东南角. ...

  5. Pycharm快捷键配置

    1.主题 毫无疑问Pycharm是一个具有强大快捷键系统的IDE,这就意味着你在Pycharm中的任何操作,例如打开一个文件.切换编辑区域等,都可以通过快捷键来实现.使用快捷键不仅能提高操作速度,看起 ...

  6. php7 中?? 和 ?:的区别

    $b = $a?? $c ;相当于$b= isset($a)?$a:$c; $b = $a?: $c ;则是 $b = !empty($a) ? $a:$c;

  7. Shiro源码解析-Session篇

    上一篇Shiro源码解析-登录篇中提到了在登录验证成功后有对session的处理,但未详细分析,本文对此部分源码详细分析下. 1. 分析切入点:DefaultSecurityManger的login方 ...

  8. JAVA学习5:用Maven创建第一个web项目(2)servlet演示

    上一章用Maven新建了web项目成功后,本文演示在此基础上应用servlet. 1.首先修改pom.xml文件,添加servlet依赖   <project xmlns="http: ...

  9. MyBatis整合Spring详细教程

    1整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代理 ...

  10. 案例17-validate自定义校验规则校验验证码是否输入正确

    1 自定义校验规则代码 <script type="text/javascript"> //使用validate插件进行表单的校验 $(function(){ $(&q ...