[TOC]
****
## 0 意义
Object(对象)是js中内置对象之一。可以将对象看成键值数据结构。
键值对中的键称为对象的属性只能是数字或者字符串
键值对中的值可以是任意其他类型
除了null和undefined,其他所有的都可以转换为对象
## 1 简单例子
### 1-2 对象的引用使用
~~~
var studenA = {
name:"sundway"
}
var studentB = studentA;
studentB.name = "modify";
console.log(studentA.name); //"modify"
console.log(studentB.name); //"modify"
//studentA和studentB同时是对内存中的一个引用。修改其中的一个值会影响另一个
~~~
### 1-2 对象的属性只能是字符串或者数字
~~~
var studentA = {
"name" : "sundway"
}
var studentA = {
1 : "sundway
}
console.log(studentA[1]); //输出"sundway"
//属性为数字时,不能使用.运算符读取属性值,只可以使用[]读取属性值
~~~
### 1-3 除了null和undefined转换到对象
~~~
2.toString(); // Uncaught SyntaxError
2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first
~~~
## 2 对象属性
### 2-1 属性描述
属性描述符:包含数据描述符和存储描述符
数据描述符(configurable,enumerable,value,writable)
数据描述符实现对数据可写或不可写值的属性信息描述
存取描述符(configurable,enumerable,get,set)
存储描述符由一对getter-setter函数来描述属性
描述符鄙视两种形式之一,不能同时是两者
### 2-2 Object.prototype
对象的原型对象属性,
所有对象都是基于Object,通过指定Object.prototype为特定对象
可以实现对象对其他对象的属性和方法继承,也可以被覆盖
### 2-3 Object.prototype.constructor
指向创建该对象原型的函数引用
属性的值是一个函数本身。
### 2-4 Object.prototype.__proto__
对象的proto属性和自己内部的Protototype指向相同的值
原型的值可以是一个对象也可以是Null。
使用Object.getPrototypeOf获取对象的原型
## 3 对象方法
### 3-1 Object.create() 创建一个新的对象
~~~
;模拟实现
if(typeof Object.create != 'function'){
Object.create = (function(){
//为了节省内存,使用一个共享的构造器
function Temp() {};
// 使用 Object.prototype.hasOwnProperty 更安全的引用
var hasOwn = Object.prototype.hasOwnProperty;
return function (O) {
// 1. 如果 O 不是 Object 或 null,抛出一个 TypeError 异常。
if (typeof O != 'object') {
throw TypeError('Object prototype may only be an Object or null');
}
// 2. 使创建的一个新的对象为 obj ,就和通过
// new Object() 表达式创建一个新对象一样,
// Object是标准内置的构造器名
// 3. 设置 obj 的内部属性 [[Prototype]] 为 O。
Temp.prototype = O;
var obj = new Temp();
// 不要保持一个 O 的杂散引用(a stray reference)...
Temp.prototype = null;
// 4. 如果存在参数 Properties ,而不是 undefined ,
// 那么就把参数的自身属性添加到 obj 上,就像调用
// 携带obj ,Properties两个参数的标准内置函数
// Object.defineProperties() 一样。
if (arguments.length > 1) {
// Object.defineProperties does ToObject on its first argument.
var Properties = Object(arguments[1]);
for (var prop in Properties) {
if (hasOwn.call(Properties, prop)) {
obj[prop] = Properties[prop];
}
}
}
// 5. 返回 obj
return obj;
};
})()
}
~~~
### 3-2 Object.is() 判断两个值是否同一个值
~~~
;基于===模拟实现
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
~~~
### 3-3 Object.assign(target,...sources) 拷贝源对象到目标对象,返回目标对象
~~~
;模拟实现
if (!Object.assign) {
Object.defineProperty(Object, "assign", {
enumerable: false,
configurable: true,
writable: true,
value: function(target, firstSource) {
"use strict";
if (target === undefined || target === null)
throw new TypeError("Cannot convert first argument to object");
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) continue;
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) to[nextKey] = nextSource[nextKey];
}
}
return to;
}
});
}
~~~
~~~
;Demo 拷贝symbol类型的属性
var o1 = { a: 1 };
var o2 = { [Symbol("foo")]: 2 };
var obj = Object.assign({}, o1, o2);
console.log(obj); // Object {a: 1, Symbol(foo): 2}
;继承属性和不可枚举属性是不能拷贝的
var obj = Object.create({foo: 1}, { // foo 是个继承属性。
bar: {
value: 2 // bar 是个不可枚举属性。
},
baz: {
value: 3,
enumerable: true
}
});
var copy = Object.assign({}, obj);
console.log(copy); // Object {baz: 3}
;原始值会被隐式转换为其他包装对象
var v1 = "123";
var v2 = true;
var v3 = 10;
var v4 = Symbol("foo")
var obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// 源对象如果是原始值,会被自动转换成它们的包装对象,
// 而 null 和 undefined 这两种原始值会被完全忽略。
// 注意,只有字符串的包装对象才有可能有自身可枚举属性。
console.log(obj); // { "0": "1", "1": "2", "2": "3" }
;拷贝过程中发生异常
var target = Object.defineProperty({}, "foo", {
value: 1,
writeable: false
}); // target 的 foo 属性是个只读属性。
Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});
// TypeError: "foo" is read-only
// 注意这个异常是在拷贝第二个源对象的第二个属性时发生的。
console.log(target.bar); // 2,说明第一个源对象拷贝成功了。
console.log(target.foo2); // 3,说明第二个源对象的第一个属性也拷贝成功了。
console.log(target.foo); // 1,只读属性不能被覆盖,所以第二个源对象的第二个属性拷贝失败了。
console.log(target.foo3); // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的。
console.log(target.baz); // undefined,第三个源对象更是不会被拷贝到的。
~~~
### 3-4 Object.keys(obj) 返回对象的可枚举自身属性的属性名组成的数组
### 3-5 Object.defineProperty(obj,prop,descriptor)
直接在对象上定义一个新属性,并返回这个对象
### 3-6 Object.defineProperties(obj,props)
在一个对象上添加或修改一个或者多个自由属性,并返回这个对象
### 3-7 Object.freeze(obj)
冻结一个对象。这个对象不可改变
### 3-8 Object.isFrozen(obj)
判断一个对象是否被冻结
### 3-9 Object.preventExtensions(obj)
禁止一个对象可扩展,永远不可能对对象添加新的属性
### 3-10 Object.isExtensible(obj)
## 4 资源
[js中的object](https://segmentfault.com/a/1190000004224842)
- 概述
- 框架结构
- 编译入口(\entries)
- web-compiler.js(web编译)
- web-runtime.js(web运行时)
- web-runtime-wih-compiler.js(web编译运行)
- web-server-renderer.js(web服务器渲染)
- 核心实现 (\core)
- index.js(核心入口)
- config.js(核心配置)
- core\util(核心工具)
- core\observer(双向绑定)
- core\vdom(虚拟DOM)
- core\global-api(核心api)
- core\instance(核心实例)
- 模板编译(\compiler)
- compiler\parser(模板解析)
- events.js(事件解析)
- helper.js(解析助手)
- directives\ref.js(ref指令)
- optimizer.js(解析优化)
- codegen.js(渲染生成)
- index.js(模板编译入口)
- web渲染(\platforms\web)
- compiler(web编译目录)
- runtime(web运行时目录)
- server(web服务器目录)
- util(web工具目录)
- 服务器渲染(\server)
- render-stream.js(流式渲染)
- render.js(服务器渲染函数)
- create-renderer.js(创建渲染接口)
- 框架流程
- Vue初始化
- Vue视图数据绑定
- Vue数据变化刷新
- Vue视图操作刷新
- 框架工具
- 基础工具(\shared)
- 模板编译助手
- 核心实例工具
- Web渲染工具
- 基础原理
- dom
- string
- array
- function
- object
- es6
- 模块(Module)
- 类(Class)
- 函数(箭头)
- 字符串(扩展)
- 代理接口(Proxy)
- 数据绑定基础
- 数据绑定实现
- mvvm简单实现
- mvvm简单使用
- vdom算法
- vdom实现
- vue源码分析资料