prototype of object

prototype这关键字,很好理解,原型嘛! 每个对象上都有一个prototype原型对象,最终将指向Object的prototype,Object的prototype有指向null,所以,在js中,任何一个对象,在原型链的最顶端都是null
构造方法或是函数,通过new 操作符构造出来的对象叫实例对象,通过函数对象上的prototype的属性或方法叫原型对象eg:

function A(name,age){
  this.name = name;
  this.age = age;
  this.m = function(){
    console.log(11);
  }
}
A.prototype.sayHello = function(){
  return this.name;
}
var a = new A('aa',11);
var b = new A('bb',22);
a.name // aa 实例属性
b.name // 'bb'
a.sayHello() // 'aa' 原型上的方法
b.sayHello() // 'bb' 
a.toString() // 能调用该方法,其原型prototype链上继承自Object上的原型方法

实际上在调用其属性或是方法的时候,首先是在自己的对象中查找,(这里的对象便是new操作符构造的一个对象,前文说过使用new操作符)若是在自身对象中没有找到需要调用的属性或方法,则就会通过原型prototype进行链式查找,直到找到最顶端null为止,若还是没有找到,则返回undefined
在上述代码中,每一次new出来的对象,都是一个全新的对象,所以a.m !== b.m 但是a,b都能调用sayHello方法,是因为sayHello方法在A的原型prototype上,新生成的实例是共享该方法,这便达到代码重复利用的目的
对于这种原型共享属性或方法,同样也会有一些局限,比如直接改变prototype中的值时,下面的实例对象对应到的属性或方法同样会跟着改变,这就想当于是源头改变了,对应的指向当然也得改变eg:

function A(){
 this.a = 1;
}
A.prototype.b = 1;
var a = new A();
var a1 = new A();
a.b // 1
a1.b // 1
a.prototype.b = 3;
a.b // 3
a1.b // 3

当直接改变A构造方法原型上的属性b时,通过A构造的所有实例对象上的属性b也跟着改变了,实际上通过调用a.b或是a1.b找到的是A.prototype.b,若所生成的实例中存在b属性,则不会再去A的原型prototype中寻找属性b
原型链
js规定任何对象都有一个prototype原型对象,在使用这个对象时,js会在自身对象及原型对象上一层层的往上寻找属性,直到Object.prototype,若Object.prototype还是找不到,则返回undefined,因为Object.prototype指向的是null,也是所有对象的最顶端

function A(){}
A.prototype = new Array();
A.prototype.constructor = A;
var a = new A();
a.push(3)
a //[3]
a.length // 1
a instanceof Array // true

这说明对象的prototype原型是可以随意改变指向的,通常我们在改变prototype原型指向的时候还需要将prototype.constructor改正回来正确的指向,不然在使用instanceof来判断的时候可能会出现错误eg:

var obj = Object.create(null);
typeof obj // "object"
Object.create(null) instanceof Object // false

通过instanceof操作符,我们可以解决在调用构造函数忘记写new操作符的问题eg:

function A(a,b){
 if(this instanceof A){
   this.a = a;
   this.b = b;
 }else{
   return new A(a,b);
 }
}

通过constructor可以知道某个实例对象到底是哪个构造函数生成的

function A(){}
A.prototype.constructor === A // true
var a = new A()
a.constructor === A // true
a.hasOwnProperty('constructor') // false
A.prototype.hasOwnProperty('constructor') // true

说明constructor是在函数对象的原型prototype上的,所以a.hasOwnProperty('constructor')返回的是false

PHP Warning: curl_exec() has been disabled for security reasons in /home/ftp/f/free49568/wwwroot/wp-content/themes/Variant/functions.php on line 490 百度已收录
分享