1.语法
对象可以通过两种形式定义:声明形式和构造形式
声明形式
var myObj = {
key: value
};
构造形式
var myObj = new Object();
myObj.key = value;
2.类型
string
number
boolean
null
undefined
object
3.内置对象
String
Number
Boolean
Object
Function
Array
Date (日期)
RegExp (正则表达式)
Error (异常)
var strPrimitive = "I am a string";
console.log(typeof strPrimitive);
console.log(strPrimitive instanceof String);
var strObject = new String("I am a string");
console.log(typeof strObject);
console.log(strObject instanceof String);
console.log(Object.prototype.toString.call( strObject ));

tips:
typeof
用于判断数据类型,返回值为6个字符串,分别为string、Boolean、number、function、object、undefined。
instanceof
instance中文翻译为实例,因此instanceof的含义就不言而喻,判断该对象是谁的实例,同时我们也就知道instanceof是对象运算符。
这里的实例就牵扯到了对象的继承,它的判断就是根据原型链进行搜寻,在对象obj1的原型链上如果存在另一个对象obj2的原型属性,那么表达式(obj1 instanceof obj2)返回值为true;否则返回false
strPrimitive为原始值,对象字面量,js中在必要的时候字面量会转换成对象
null,undefined只有文字形式(大括号的那种创建),Date只有构造形式(new)
Object,Array,Function,RegExp无论是哪种形式,它们都是对象,而不是字面量
3.内容
var myObject = {
a: 2
};
myObject.a;
myObject["a"];
两种访问方式都可以访问到对应的值, 前者是属性访问(必须符合标识符规范),后者是键访问(utf-8、unicode)
在对象中,属性名始终都是字符串,即使不是字符串也会转换成字符串
1.可计算属性名
var prefix = "foo";
var myObject = {
[prefix + "bar"]:"hello",
[prefix + "baz"]:"world"
};
myObject["foobar"]; //hello
myObject["foobaz"]; //world
prefix + 字符串成为了属性名的名字
2.属性与方法
每次访问对象的属性就只能是属性访问,即使返回的是一个函数,也并不是方法,只是一个普通的函数
3.数组
js中的数组与其他语言的数组略有些区别,
var myArray = ["foo",42,"bar"];
myArray.baz = "baz";
myArray.length = 3; //3
myArray.baz; //"baz"
数组可以添加属性名,而且数组的长度并不会变化,但并不推荐这么用数组,如果你的属性名看起来像数组的话就将直接修改数组里面的值
4.复制对象
浅拷贝: 浅拷贝出来的对象和原来的对象在同一空间,只是引用
深拷贝:重新开辟一片空间,两个对象并不公用同一空间
es6中定义了Object.assign来实现浅复制
var newObj = Object.assign({},myObject);
第一个参数是目标对象,后面可以跟一个或多个源对象
5.属性描述符
从es5开始,所有的属性都具备了属性描述符
var myObject = {
a:2
};
Object.getOwnPropertyDescriptor( myObject,"a",{
value: 2,
writable: true,
enumerable: true,
configurable: true
)
在创建普通属性时会使用默认值,我们也可以使用Object.defineProperty来添加新属性或修改已有的属性
将可写置为false,则不能修改对象的属性值,严格模式下会报错typeError
var myObject = {};
Object.defineProperty( myObject,"a", {
value: 2,
writable: false,
configurable: true,
enumerable: true
});
myObject.a = 3;
myObject.a //2
将configurable修改为false之后则不能对属性描述符进行修改,进行修改则会报错,无论是在严格模式下还是非严格模式下都会报错,所以configurable修改为false是一个单向操作无法修改,甚至delete操作都会失败,因为delete是删除对象的属性来对元素进行删除的,而将configurable修改为false就无法进行删除了
最后,enumerable是控制对象的属性能不能出现在属性枚举中,比如for ... in 循环
6.不变性
1.对象常量:将writable和configurable全部设置为false,不可修改或删除
2.禁止扩展: Object.preventExtensions(..);
3.密封:Object.seal()不能做任何的修改,也无法重新配置或删除现有的属性。这个方法实际上会在一个现有对象调用Object.preventExtensions并把现有属性标记为configurable:false
4.冻结:Object.freeze(),这个方法实际上是调用Object.seal()并把数据访问属性标记为writable:false
7.[[Get]]
var myObject = {
a:2
};
myObject.a;
myObject.a在myObject实际上实现了[[get]]操作,如果[[get]]找不到对应的属性的话,那么它们将会返回undefined
8.[[getter]],[[setter]]
var myObject = {
get a() {
return 2;
}
};
Object.defineProperty(
myObject,
"b",
{
get: function() { return this.a*2;},
enumerable: true
}
};
myObject.a; //2
myObject.b; //4
9.存在性
var myObject = {
a:2
};
("a" in myObject); //true
("b" in myObject); //false
myObject.hasOwnProperty(" a "); //true
myObject.hasOwnProperty(" b "); //false
in操作符会检查属性是否在对象及其[[prototype]]原型链中,hasOwnProperty(...)只会检查属性是否在myObject对象中,不会检查[[prototype]]链
propertyIsEnumerable(...)会检查给定的属性名是否直接存在于对象并且可枚举
Object.keys(...)返回一个数组,包括所有可枚举属性
Object.getOwnPropertyNames(...)会返回一个包含所有属性的数组,无论是否可枚举
4.遍历
forEach(...)会遍历数组中的所有值并忽略回调函数的返回值
every(...)会一直运行到回调函数返回false,some(...)会一直运行直到回调函数返回true
本文深入探讨JavaScript对象的定义、类型、内置对象、属性访问、复制、属性描述符、不变性等核心概念,揭示JS对象的独特特性和高效使用技巧。
4629

被折叠的 条评论
为什么被折叠?



