原型,原型链

200 阅读4分钟

一、构造函数

构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立的,即实例识别。

构造函数和普通函数的区别: 构造函数就是一个普通的函数,创建方式和普通函数没有区别,

不同的是构造函数习惯上首字母大写。 调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用。

    function Person(name, age, gender) {
        this.name = name
        this.age = age
        this.gender = gender
        this.sayName = function () {
            alert(this.name);
        }
    }
    var per = new Person("孙悟空", 18, "男");
    function Dog(name, age, gender) {
        this.name = name
        this.age = age
        this.gender = gender
    }
    var dog = new Dog("旺财", 4, "雄")
    console.log(per);//当我们直接在页面中打印一个对象时,事实上是输出的对象的toString()方法的返回值
    console.log(dog);

二、为什么需要原型(prototype)

每创建一个Person构造函数,在Person构造函数中,为每一个对象都添加了一个sayName方法

也就是说构造函数每执行一次就会创建一个新的sayName方法。这样就导致了构造函数执行一次就会创建一个新的方法,执行10000次就会创建10000个新的方法,而10000个方法都是一摸一样的,为什么不把这个方法单独放到一个地方,并让所有的实例都可以访问到呢?这就需要原型(prototype)

好处:使用原型的好处就是可以让所有的对象实例共享原型对象所包含的属性和方法

三、原型

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性是一个指针,指向函数的原型对象,并且这个属性是一个对象数据类型的值。

让我们用一张图表示构造函数和实例原型之间的关系:

理解:1.函数类型自带一个prototype 属性; 2.这个属性的值是一个对象; 3.这个属性的值(这个属性指向)此函数的原型对象,(一个公共的地方)

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。

三、原型链

1.proto__和constructor 每一个对象数据类型(普通的对象、实例、prototype......(除Object))也天生自带一个属性__proto,。属性值是当前实例所属类的原型(prototype)。原型对象中有一个属性constructor, 它指向函数对象

注意constructor

function Person() {

}
var person = new Person();
console.log(person.constructor === Person); // true

当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以:

     person.constructor === Person.prototype.constructor

2.何为原型链 所谓原型链,指的就是图中的proto这一条指针链! 原型链的顶层就是Object.prototype,而这个对象的是没有原型对象的。如chrome的控制台输出 :

当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined。

四、prototype和__proto__的区别

五、创建的对象中__proto__指向谁

总结:

一、isPrototypeOf()

某个prototype对象和某个实例之间的关系 function A(){} var a=new A() A.prototype.isPrototypeOf(a)

二、hasOwnProperty() 每个实例都有一个hasOwnProperty()方法,用来判断某一个属性是不是本地属性,还是继承自prototype对象的属性

a.hasOwnProperty('name')

三、in运算符

判断某个实例是否含有某个属性,不管是本地的属性还是prototype对象上的属性 'name' in cat1