js原型prototype问题

什么是js原型?

在js中创建对象是通过构造函数来完成的

构造函数?

在js中构造函数就相当于一个普通函数,只不过构造函数的命名通常首字母大写

function Person(){

}

构造函数中this指向的是利用构造函数新建的对象

function Person(){
  this.name="koko";
  this.age=18;
}

普通函数可以直接调用,而构造函数需要通过new关键字调用,创建一个对象

var per = new Person();

通过this.name="koko"的方式,使得每一个对象的name值都为koko

如果想不写死,动态的决定每一个对象的name,这就需要参数了,让对象调用构造函数时,自己决定,自己传值

function Person (name,age) {
  this.name=name;
  this.age=age;
}

var per = new Person("jerry",21);
  
这样创建的对象除了属性一样外,并没有其他的任何联系,对象之间无法共享属性和方法。
每当我们新建一个对象时,都会方法和属性分配一块新的内存,这是极大的资源浪费。
考虑到这一点,JavaScript 的设计者决定为构造函数设置一个属性,叫 prototype。
而构造函数创建的对象中也有一个对应的隐含的属性,叫 __proto__。
这个属性指向一个对象,叫原型(对象),所有对象需要共享的属性和方法,都放在这个对象里面,不需要共享的属性和方法,就放在构造函数里面。
实例对象一旦创建,将自动引用这个对象的属性和方法。
也就是说,实例对象的属性和方法,分成两种:一种是本地的,不共享的。另一种是放在另一片共享区域的,是引用的,共享的。
(per.__proto==Person.prototype)

true

我们知道每个函数都有一个 prototype 属性,指向函数的原型。

因此当我们拿到一个函数的时候,就可以确定函数的原型。

反之,如果给我们一个函数的原型,我们怎么知道这个原型是属于哪个函数的呢?

这就要提到原型的 constructor 属性了。

在默认情况下,所有原型对象都会自动获得一个 constructor (念作:构造函数)属性,也就是说每个原型都有都有一个 constructor 属性。

这个属性包含一个指向 prototype 属性所在函数的指针,指向了原型所在的函数。

比如:Person.prototype.constructor 指向 Person。

也就是构造函数的原型的构造函数,指向构造函数。

如何判断一个对象与原型是否存在关系?

当我们想要确定一个对象实例和某个原型之间是否存在关系时,我们有一些方法可以判断,我们可以通过 isPrototypeOf() 方法判断某个原型和对象实例是否存在关系

或者,我们也可以使用 ES5 新增的方法 Object.getPrototypeOf() 获取一个对象实例 __proto__ 属性的值。

console.log(Person.prototype.isPrototypeOf(person1)); // true

console.log(Object.getPrototypeOf(person1) == Person.prototype); // true

 向原型对象中加入属性和方法的方式

Person.prototype.age = '20';
Person.prototype.sayName
= function() { console.log(this.name); }

不能通过字面量的方式加入,因为字面量的方式会创建一个新的对象

Person.prototype = {
  constructor: Person,
  name: "Nicholas",
  age: 29,
  job: "Software Engineer",
  sayName: function () {
    console.log(this.name);
  }
};

person.sayName(); // error

也就是说这里的 Person.prototype 是一个新的对象,和 person 的 __proto__ 属性不再有任何关系了

 

 

原型的原型:

//Person构造函数
function Person() {
  this.age = '20';
}

//向Person的原型中添加一个属性weight
Person.prototype.weight = '120';

//Engineer构造函数
function Engineer() {
  this.work = 'Front-End';
}

//把Engineer的原型变成Person的实例对象
//也就是说,Engieer的原型的原型是Person

//这也是用继承的方式 Engineer.prototype = new Person();

 原型链:

按照名字就可以知道,就是原型之间形成的一个链条。

那么原型链的末端又是什么呢?

是 Object ,因此默认原型都会包含一个内部指针,指向 Object.prototype

console.log(Person.prototype.__proto__ == Object.prototype); // true

Object.prototype 又是什么呢,是 null 

posted @ 2019-08-09 21:09  白泽霜  阅读(108)  评论(0编辑  收藏  举报