您好,欢迎访问一九零五行业门户网

详解JS原型和原型链(一)

这次给大家带来详解js原型和原型链以及注意事项有哪些,下面就是实战案例,一起来看一下。
一. 普通对象与函数对象
javascript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,object 、function 是 js 自带的函数对象。下面举例说明
var o1 = {}; var o2 =new object(); var o3 = new f1(); function f1(){}; var f2 = function(){}; var f3 = new function('str','console.log(str)'); console.log(typeof object); //function console.log(typeof function); //function console.log(typeof f1); //function console.log(typeof f2);//function console.log(typeof f3);//function console.log(typeof o1);// object console.log(typeof o2);//object console.log(typeof o3); //object
在上面的例子中 o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。怎么区分,其实很简单,凡是通过 new function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new function()的方式进行创建的。function object 也都是通过 new function()创建的。
一定要分清楚普通对象和函数对象,下面我们会常常用到它。
二. 构造函数
我们先复习一下构造函数的知识:
function person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayname = function() { alert(this.name) } } var person1 = new person('zaxlct', 28, 'software engineer'); var person2 = new person('mick', 23, 'doctor');
上面的例子中 person1 和 person2 都是 person 的实例。这两个实例都有一个 constructor (构造函数)属性,该属性(是一个指针)指向 person。 即:
console.log(person1.constructor == person); //true console.log(person2.constructor == person); //true
我们要记住两个概念(构造函数,实例):
person1 和 person2 都是 构造函数 person 的实例
一个公式:
实例的构造函数属性(constructor)指向构造函数。
三. 原型对象
在 javascript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。(先用不管什么是 __proto__ 第二节的课程会详细的剖析)
function person() {} person.prototype.name = 'zaxlct'; person.prototype.age = 28; person.prototype.job = 'software engineer'; person.prototype.sayname = function() { alert(this.name); } var person1 = new person(); person1.sayname(); // 'zaxlct'var person2 = new person(); person2.sayname(); // 'zaxlct'console.log(person1.sayname == person2.sayname); //true
我们得到了本文第一个「定律」:
每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性
那什么是原型对象呢?
我们把上面的例子改一改你就会明白了:
person.prototype = { name: 'zaxlct', age: 28, job: 'software engineer', sayname: function() { alert(this.name); } }
原型对象,顾名思义,它就是一个普通对象(废话 = =!)。从现在开始你要牢牢记住原型对象就是 person.prototype ,如果你还是害怕它,那就把它想想成一个字母 a: var a = person.prototype
在上面我们给 a 添加了 四个属性:name、age、job、sayname。其实它还有一个默认的属性:constructor
在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(person)
上面这句话有点拗口,我们「翻译」一下:a 有一个默认的 constructor 属性,这个属性是一个指针,指向 person。即:
person.prototype.constructor == person
在上面第二小节《构造函数》里,我们知道实例的构造函数属性(constructor)指向构造函数 :person1.constructor == person
这两个「公式」好像有点联系:
person1.constructor == person
person.prototype.constructor == person
person1 为什么有 constructor 属性?那是因为 person1 是 person 的实例。
那 person.prototype 为什么有 constructor 属性??同理, person.prototype (你把它想象成 a) 也是person 的实例。
也就是在 person 创建的时候,创建了一个它的实例对象并赋值给它的 prototype,基本过程如下:
var a = new person();
person.prototype = a;
结论:原型对象(person.prototype)是 构造函数(person)的一个实例。
原型对象其实就是普通对象(但 function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:
function person(){}; console.log(person.prototype) //person{} console.log(typeof person.prototype) //object console.log(typeof function.prototype) // function,这个特殊 console.log(typeof object.prototype) // object console.log(typeof function.prototype.prototype) //undefined
function.prototype 为什么是函数对象呢?
var a = new function (); function.prototype = a;
上文提到凡是通过 new function( ) 产生的对象都是函数对象。因为 a 是函数对象,所以function.prototype 是函数对象。
那原型对象是用来做什么的呢?主要作用是用于继承。举个例子:
var person = function(name){ this.name = name; // tip: 当函数执行时这个 this 指的是谁? }; person.prototype.getname = function(){ return this.name; // tip: 当函数执行时这个 this 指的是谁? } var person1 = new person('mick'); person1.getname(); //mick
从这个例子可以看出,通过给 person.prototype 设置了一个函数对象的属性,那有 person 的实例(person1)出来的普通对象就继承了这个属性。具体是怎么实现的继承,就要讲到下面的原型链了。
小问题,上面两个 this 都指向谁?
var person1 = new person('mick'); person1.name = 'mick'; // 此时 person1 已经有 name 这个属性了 person1.getname(); //mick
故两次 this  在函数执行时都指向 person1。
以上就是详解js原型和原型链(一)的详细内容。
其它类似信息

推荐信息