javascript原型

想了解原型的朋友一定被许多开篇既是原型多么难理解给吓着了吧,其实原意应该是原型是一个非常重要的概念,但是理解起来并不困难,前面的原型链 __proto__ 已经把原型说了一大半,但是那是返回对象之后取到的原型对象,虽然它们指向的是同一个内存地址,但是也需要理解一下它的由来。

你可以理解成 __proto__ 是这样得来的。

var prototype = {};
var __proto__ = prototype;
//直接把__proto__指向prototype的内存地址

言归正传,上面只是一个例子,真正的prototype指的是函数的属性,这个属性是javascript为函数内置的属性,这个属性有几个特点

  • 这个属性是一个对象(每个对象都会有一个__proto__的属性)
var fn = function(){};
var obj = fn.prototype; //这是一个对象
obj.__proto__.__proto__ //这就是原型链的表现
//**.__proto__.__proto__***.__proto__ 如果原型链够长会是这样的。
  • 这个对象可以被改变,javascript内置的构造函数不能被重新赋值但是可以在上面添加属性
//这样操作并不能改变Function的prototype的值
Function.prototype = 123;
//但是可以添加
Function.prototype.add = 1;
//非内置函数可以被修改
var fn = function(){};
fn.prototype = 1; //这样已经被修改

所以尽量避免覆盖prototype的值

javascript内置构造函数
Function 函数的构造器 new Function()
Array 数组的构造器  new Array()
Object 对象的构造器 new Object()
Error 错误对象的构造器 new Error()
RegExp 正则的构造器   new RegExp
Date 时间对象的构造器 new Date()
String 字符串构造器 new String()
Boolean 布尔值构造器 new Boolean()
Number 数值的构造器 new Number()
……
  • 通过 new 返回一个对象,这个对象的 __proto__ 属性指向的就是通过new执行的构造函数的prototype
var Fn = function(){};
Fn.prototype.add = "123";
var obj = new Fn();
//obj的__proto__指向的就是Fn.prototype
obj.__proto__ == Fn.prototype // true

重点地方应该加“粗”变“长”应该更容易吸引人

  1. 通过new执行构造函数返回一个新对象
  2. 这个对象拥有一个 __proto__ 的属性
  3. 这个 __proto__ 属性指向构造函数的prototype

 玩完以上三篇,下面来玩一盘原型继承

//利用debugger看看每一步的走向
debugger;
//创建一个构造函数
//这个构造函数将被继承
var Parent = function() {
    this.param1 = "my is param1"
}
//为这个构造函数的prototype添加一个属性
Parent.prototype.param2 = "my is param2";
//创建第二个需要继承的构造函数
var Child = function(){ 
    this.param3 = "my is param3";    
}
//把这个构造函数的prototype重新赋值
//赋值为通过new执行Parent函数返回的对象
//new出来的对象是一个朴素对象
//这个对象会继承Object对象
//Child.prototype这个对象也会继承Object对象
//所以对它进行覆盖不会出现意外的错误
Child.prototype = new Parent();
Child.prototype.param4 = "my is param4";
//把构造器指回Child,用于明确这个创建这个对象的构造函数
//这个属性可以被修改,所以不要忘了这一步。
Child.prototype.constructor = Child;
//最后返回一个拥有这两个构造函数的属性的对象
//这个对象将拥有这些属性
var newObject = new Child();
//它的结构应该是这样的
//  {
//     param3:"my is param3",
//     "__proto__":{
//         constructor:Child,
//         param4:"my is param4",
//         param1:"my is param1",
//         "__proto__":{
//             param2:"my is param2",
//             constructor:Parent
//             "__proto__":{
//                 ......
//             }
//         }
//     }
// }

 

posted @ 2016-06-01 00:23  mro  阅读(205)  评论(0编辑  收藏  举报