JS原型对象

121 阅读3分钟

JS原型对象

一,构造函数,原型对象,实例的关系:

1,构造函数实例:封装的函数,如果通过new操作符来调用的,就是构造函数,如果没有通过new操作符来调用的,就是普通函数 2,函数Person(对象)有个属性prototype(指针)指向原型对象。 Person.prototype(原型对象,实质也是对象),他有个属性constructor(指针) ,又指向 Person函数对象

console.log(Person === Person.prototype.constructor); //true

3,实例对象person1有个属性[prototype](内部属性,chrome和firefix,Safari,中这个属性叫_proto_)指向原型对象。实例对象可以通过这个属性访问原型对象上的属性和方法(Perons.prototype.proto == person1.proto)。

 function Person(name, age) {
    this.name = name;
    this.age = age;
}
//在原型对象中添加属性或者方法
Person.prototype.sex = '男'; 
var person1 = new Person('Mike',10); 
var person2 = new Person('Alice',20);
//只给person2设置性别
person2.sex = '女';
console.log(person1.sex)  // '男'
console.log(person2.sex)  //'女' 

4,可以通过实例对象(person1)的constructor(person1.constructor)访问构造函数,但是constructor本质上是原型对象的属性。

二,继承:

1,继承的主要思路是利用原型链,而原型链的原理是:让一个引用类型继承另一个引用类型的属性和方法。即原型对象通过constructor指向构造函数,实例对象通过_ptoto_指向原型对象。

function A() {}

//在A的原型上绑定sayA()方法

A.prototype.sayA = function(){

    console.log("from A")

}
function B(){}

//让B的原型对象指向A的一个实例

B.prototype = new A();

//在B的原型上绑定sayB()方法

B.prototype.sayB = function(){

    console.log("from B")

}
//生成一个B的实例

var a1 = new A();

var b1 = new B();

//b1可以调用sayB和sayA

b1.sayB();//'from B'

b1.sayA();//'from A'

说明:2-1,最后我们调用了b1的sayB方法,可以执行,为什么?

因为b1有[Prototype]属性可以访问B prototype里面的方法;

2-2,我们调用了b1的sayA方法,可以执行,为什么?

因为b1沿着[Prototype]属性可以访问B prototype,B prototype继续沿着[Prototype]属性访问A prototype,最终在A.prototype上找到了sayA()方法,所以可以执行

3,JavaScript语言的传统方法是通过构造函数,定义并生成新对象,prototype 属性使您有能力向对象添加属性和方法。下面是通过传统的方式创建和使用对象的案例:

//Person.js文件
function Person(x,y){ this.x = x; this.y = y; }
Person.prototype.name = 'sky';  //原型对象上的属性 
Person.prototype.toString = function (){ //原型对象上的方法 

  return (this.x + "的年龄是" +this.y+"岁"); 

} 
export {Person}; 

//index.js文件  

import {Person} from './Person'; 

let person = new Person('张三',12);

console.log(person.toString()); 

image.png 4, 代码中,对象p的的name属性为私有变量,使用p.name不能直接访问

5,以上代码ES6 类class写法:

//Person.js

class Person{
    // 构造
    constructor(x,y){  //构造方法
        this.x = x;
        this.y = y;
    }   //方法之间不需要逗号分隔,加了会报错
    toString(){  //原型对象上的方法
        return (this.x + "的年龄是" +this.y+"岁");
    }
}

export {Person};

//index.js

import {Person} from './Person';

let person = new Person('张三',12);

console.log(person.toString());
constructor方法是类的构造函数是默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个默认的constructor方法会被添加。所以即使你没有添加构造函数,也是有默认的构造函数的。一般constructor方法默认返回实例对象this。类的方法内部如果含有this,它默认指向类的实例。。(个人理解:

Person.prototype = this = person1

Person.prototype.constructor = Person,

person1.constructor == Person

person1.__proto__ === person1.constructor.prototype)

6,下面 这个类的名字是Expression而不是Expre,Expre只在Class的内部代码可用,指代当前类。

const Expression = class Expre{

static getAge(){

    return '12';

}

getClassName(){

    return " ClassName1= " +Expre.name + " ClassName2= " +Expression.name;

}

};

let exp = new Expression();

console.log(exp.getClassName());//ClassName1= Expre ClassName2= Expre
console.log(Expression.getAge());