码迷,mamicode.com
首页 > 其他好文 > 详细

[重点] 原型链详解

时间:2016-03-19 22:55:14      阅读:312      评论:0      收藏:0      [点我收藏+]

标签:


回顾js 内存分配以及垃圾回收


- 垃圾回收查看笔记: js 内存篇


js 变量内存存放位置


- 基本类型的变量存放在
- 引用对象(包括new 出来的对象)的值放在中, 而在栈中存放一个指针指向堆中的值(所以表面上变量都是存放在栈)
技术分享


js 几个重要的概念


Function: 函数对象

Object: 对象

prototype 属性 : 

        - 指向一个对象(原型对象)原型对象是js为了实现继承代码复用, 而暴露给程序员的类似原型链的一个开放接口
        - 原型对象包括程序员定义的复用的方法和属性等, 包括constructor属性
        - 每一个函数对象在创建时都会创建一个prototype属性(只有函数对象有), 指向改函数的原型对象

__proto__ 属性 :

        - 指向一个对象, 是内部属性(chrome firefox 能用 __proto__的形式访问), 可以理解为js 内部真正的原型链
        - 每个对象都会在其内部初始化__proto__,当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性, 直到为空
        - Object.prototype.__proto__ 指向 null, 原型链从这里结束


Function 和 Object 的关系


技术分享
[注意]
        - 图中代码执行可得
    1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Object.O1 = ""// Object对象添加属性O1
    Object.prototype.Op1 = ""// Object原型对象添加属性Op1
 
    Function.F1 = "";
    Function.prototype.Fp1 = "";
 
    function Cat() {}
    Cat.C1 = "";
    Cat.prototype.Cp1 = "";
 
    var cat = new Cat(); // cat.__proto__ = Cat.prototype
    var o = {};
 
    console.log(cat); // Cat {Cp1: "", Op1: ""}
    console.log(o); // Object {Op1: ""}
        - Function.__proto__ 和 Object.__proto__和 普通函数对象Cat.__proto__ 都指向Function.prototype对象, 也就是我们说的 函数字面量创建的对象都连接到 Function.prototype
        - Function.prototype.__proto__ 和 普通函数对象(继承会影响)Cat. prototype.__proto__ 都指向Object.prototype对象(父对象的.prototype)也就是我们说的 对象字面量创建的对象都连接到 Object.prototype
        - 普通对象的__proto__指向 Object.prototype对象


new 的过程: p.__proto__ = Person.prototype;


- 先看以下代码
1
    2
var Person = function() {};
var p = new Person();
- new 的过程分为3步
    1
2
3
var p = {}; // 初始化一个空对象p。
p.__proto__ = Person.prototype; // 关键!!!!!!!!
Person.call(p); // 也就是说构造p,也可以称之为初始化p。
- 更复杂的例子:
    1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Person 类
var Person = function() {};
Person.prototype.Say = function () {
    alert("Person say");
}
Person.prototype.Salary = 50000;
 
// Programmer 类
var Programmer = function () { };
Programmer.prototype = new Person(); // Programmer.prototype.__proto__ == Person.prototype
Programmer.prototype.WriteCode = function () {
    alert("programmer writes code");
};
Programmer.prototype.Salary = 500;
 
//测试
var p = new Programmer(); // p.__proto__ = Programmer.prototype,p.__proto__.__proto__ = Person.prototype 
p.Say();
p.WriteCode();
alert(p.Salary);
        - 在p.say() 时, p中木有say(), 所以去p.__proto__找, 发现也没有就去p.__proto__.__proto__找


构造函数返回值


概念

在传统语言中,构造函数不应该有返回值,实际执行的返回值就是此构造函数的实例化对象。而在js中构造函数可以有返回值也可以没有。

返回类型: 

没有返回值: 返回实例化的new对象

返回值是非引用类型(如基本类型): 返回其实例化的new对象

返回值是引用类型: 返回这个引用类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1 无返回值
function F() {} // undefined
new F(); // F{}, 无影响
 
// 2 返回返回值是基本类型
function F() { // undefined
  return true
new F(); // F{}, 无影响
 
// 3 返回返回值是引用类型
function F() { // undefined
  return {
    a: 1
  };
new F(); // Object {a: 1}, new 返回的是 该引用对象


instanceof 运算符


- 以下代码, 会不会觉得很晕
1
2
3
4
5
6
7
8
9
 console.log(Object instanceof Object);//true 
 console.log(Function instanceof Function);//true 
 console.log(Number instanceof Number);//false 
 console.log(String instanceof String);//false 
 
 console.log(Function instanceof Object);//true 
 
 console.log(Foo instanceof Function);//true 
 console.log(Foo instanceof Foo);//false
- 其实 instanceof 的运行机制如下代码
1
2
3
4
5
6
7
8
9
10
11
 function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
  var O = R.prototype;// 取 R 的显示原型
  L = L.__proto__;// 取 L 的隐式原型
  while (true) { // 沿着原型链遍历
    if (L === null
      return false
    if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true 
      return true
    L = L.__proto__; 
  
 }
由上图可知 Foo.__proto__ !== Foo.prototype, so Foo instanceof Foo // false, String , Number 同理

typeof 运算符


技术分享

native object: 本地对象(引用类型)

        --  独立于宿主环境的 ECMAScript 实现提供的对象
        -- Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError, Global, Math, arguments

built-in object: 内置对象

        -- 由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现, 开发者不必实例化.
        -- Global, , Math,
        -- 其中 Global 对象创建时也会创建 Object, window, document, String, Number, Array, Boolean, Date, 等对象
        -- 其中进入函数EC时, 与创建AO, AO创建arguments 属性, 也就是Arguments对象

host object: 宿主对象

        -- 所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象.
        -- 所有BOM, DOM对象, 自定义对象

ECMA-262 规范:

        -- 本地对象, 实例化了的对象都是 "object"
        -- 本地对象或宿主对象, 未实例化的都是 "function"
        -- 宿主对象, 实例化了的对象都不会是 "undefined" "boolean" "string" "number"

技术分享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    var n1 = 1;
    var n2 = Number(1); // Number 当做一个普通的函数, 返回 数值
    var n3 = new Number(1); // Number 当作一个构造函数, 返回 数对象
    var n4 = Object(1); // 类似2
    var n5 = new Object(1); // 类似 4
    var cat = new Cat(); // 自定义
 
    console.log(typeof Number); // function
    console.log(typeof Object); // function
    console.log(typeof Function); // function
    console.log(typeof Cat); // function
    console.log(typeof n1); // number
    console.log(typeof n2); // number
    console.log(typeof n3); // object
    console.log(typeof n4); // object
    console.log(typeof n5); // object
    console.log(typeof cat); // object

create 对象创建


对象字面量创建 :  var a = {x:0 ,y:1}

new 创建 : 
var a = new Object(); // 创建空对象 =  {}
var a = new Array(); // 创建 空数组 = []

原型对象: .prototype
每个对象都有和另一个对象关联
如 new Date(); 就同时继承 Object.prototype 和 Data.prototype

Object.create(原型对象) 创建
1>. 定义: 创建一个可指定原型对象的并可以包含可选自定义属性的对象;
2> Object.create(proto [, properties]);  可选,用于配置新对象的属性;
1
2
3
4
5
6
7
8
9
10
11
12
var o = Object.create({x:1 , y: 2});  // o继承了 属性 x ,y
var o = Object.create(Object.prototype );  // 创建了一个空对象
 
function ProtoClass(){
    this.a = ‘ProtoClass‘;
    this.c = {};
    this.b = function() {
    }
}
var obj1 = Object.create(ProtoClass.prototype, {
     foo:{value: ‘obj1‘, writable: true}
})









[重点] 原型链详解

标签:

原文地址:http://www.cnblogs.com/haili042/p/5296548.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!