标签:标识 额外 方式 引用 var 复制 另一个 自动 object
对象有两种形式定义:
声明(文字)形式:
var myObj = {
key: value
// ...
};
构造形式:
var myObj = new Object();
myObj.key = value;
? 对象是JS的基础,JS中一共有六种主要类型。
? 前五个被称为 简单基本类型,本身并不是对象,执行type of null会返回obejct,这属于JS语言的一个bug。因此 JS中并不是万物皆是对象。
? JS中有许多特殊的对象子类型,称之为 复杂基本类型。
? 内置对象的表现形式很像其他语言的类型(type)或者类(class),(比如Java中的String类)。但是在JS中,这些只是一些内置函数(可以当作构造函数使用(参见本卷this详解中new绑定))。
var strPrimitive = "I am a string";
console.log(typeof strPrimitive); // string
console.log(strPrimitive instanceof String); // false
var strObject = new String("I am a string");
console.log(typeof strObject); // object
console.log(strObject instanceof String); // true
console.log(strPrimitive.charAt(3)); // m
? 对象的内容是由一些存储在特定命名位置的(任意类型的)值组成的,我们称之为属性。
var myObject = {
a: 2
};
// 属性访问:
console.log(myObject.a); // 2
// 键访问:
console.log(myObject["a"]); // 2
? 主要用于ES6中的符号(Symbol)。
? 准确来说,函数并不会属于一个对象,因此JS中的函数并不是“方法”。(即使具有this引用)。
? 数组也支持字符串作为键,但是使用数值下标经过了优化。
function anotherFunction() {
// ...
}
var anotherObject = {
c: true
};
var anotherArray = [];
var myObject = {
a: 2,
b: anotherObject, // 引用
c: anotherArray,
d: anotherFunction
};
浅拷贝在复制myObject的同时,也会去复制a的值,而b、c、d的值仍然是引用。
深拷贝则会同时复制b、c、d的值。(深拷贝可能会导致循环引用,导致死循环)
对于JSON安全的对象,可以使用:
var newObj = JSON.parse(JSON.stringify(someObj));
ES6中定义了 Object.assign(..)方法来实现浅拷贝。方法的第一个参数是 目标对象,之后可以跟一个或多个 源对象。它会遍历源对象的所有 可枚举的自由键并把它们复制到目标对象。
? 属性访问并不是简单的在对象中查找该属性。而是实现了[[Get]]操作(类似于函数调用[[Get]]())。会在对象中查找是否有名称相同的属性,如果有则返回该属性的值,如果没有则沿原型链查找。如果还是找不到则会返回undefined(如果该变量在当前词法作用域中没有定义,则会抛出ReferenceError异常)。
[[Put]]流程:
? getter和setter是隐藏函数,分别会在获取属性值、设置属性值时会被调用。
? 当类似 myObject.a这样访问属性时返回undefined,可能时属性不存在,但是也有可能该属性存储的值就是undefined。
var myObject = {
a: 2
};
console.log("a" in myObject) // true
console.log("b" in myObject) // false
console.log(myObject.hasOwnProperty("a")); // true
console.log(myObject.hasOwnProperty("b")); // false
in操作符会检查属性是否在对象及其[[Prototype]]原型链中。
hasOwnProperty(..)只会检查是否在对象中。
Object.prototype.hasOwnProperty.call(myObject, "a");
枚举 enumerable
for .. in循环可以用来遍历对象的可枚举属性列表。
数值索引的数组,可以用标准的for循环来遍历值。
for .. of循环可以直接遍历数组的值而不是数组下标。
arr = [1, 2, 3]
for (const val of arr) {
console.log(val)
};
of循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next()方法来遍历所有值。
数组有内置的 @@iterator,因此of可以直接应用在数组上。我们可以使用内置的@@iterator来手动遍历数组:
var myArray = [1, 2, 3]
var it = myArray[Symbol.iterator]();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
普通对象并没有内置的@@iterator,但是可以自己添加。
? 接受回调函数并把它应用到数组的每个元素上,唯一的区别就是它们对于回调函数返回值的处理方式不同。
标签:标识 额外 方式 引用 var 复制 另一个 自动 object
原文地址:https://www.cnblogs.com/enmac/p/13155123.html