JavaScript高级 构造函数与原型篇

构造函数与原型

1、构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

//  定义学生构造函数
 function Student() {
//   // 添加属性
   this.school = '好好好学院'
   this.age = 18
 }
 // 基于Student构造函数创建对象
 const s1 = new Student()
 const s2 = new Student()

在JS中,使用构造函数时需要注意以下两点:

        1.构造函数用于创建某一类对象,其首字母要大写

        2.构造函数要和new一起使用才有意义

new 在执行时会做四件事情:

        1.在内存中创建一个新的空对象

        2.让this指向这个新的对象

        3.执行构造函数里面的代码,给这个新对象添加属性和方法

        4.返回这个新对象所以构造函数里面不需要(return)

JavaScript 的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的 this 上添加。通过这两种方式添加的成员,就分别称为静态成员和实例成员。
实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问。
静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问 。

 function A(uname,age){
    this.uname = uname;
    this.age  = age;
    this.say = function() {
        console.log(this.uname+'你好');
    }
}

var zs = new A('张三',18);
var ls = new A('李四',18);

在上述代码中,构造函数中通过this添加的name,age,say方法都是实例成员。只能由实例化的对象来访问。在构造函数本身上添加的成员叫静态成员

例如:

A.sex = '女'

2、构造函数原型

构造函数通过原型分配的函数是所有对象共享的。JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。需要注意的是,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

function Student(age,name){
    this.age = age;
    this.name = name;
    this.score = function(){
        console.log('孩子们成绩都很好!');
    }
}

console.dir(Student);

打印该构造函数里面所有的方法,浏览器控制台:

JavaScript高级 构造函数与原型篇_第1张图片

可以找到prototype对象。

可以把一些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法了。

可以自己尝试打印一下下面的结果。

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

Student.prototype.score = function(){
    console.log('孩子们成绩都很好!');
}

console.dir(Student);
var xl = new Student(18,'小熊');
var wh = new Student(17,'王欢');
xl.score();
wh.score();
console.log(xl.score === wh.score);

需要注意的一点是:一般情况下,公共属性定义到构造函数里面,公共方法定义到原型对象身上。

3、对象原型 __proto__

对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。

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

 Student.prototype.score = function(){
     console.log('孩子们成绩都很好!');
 }

// console.dir(Student);

 var xl = new Student(18,'小熊');
 var wh = new Student(17,'王欢');
 console.log(xl);

尝试打印实例对象查看它的原型(__proto__)

console.log(xl);//对象身上系统自己添加一个__proto__属性指向构造函数的原型对象

JavaScript高级 构造函数与原型篇_第2张图片

那么对象原型(__proto__)和原型对象(prototype)是否等价

我们不妨做个测试

 console.log(xl.__proto__ === Student.prototype);

JavaScript高级 构造函数与原型篇_第3张图片

打印结果为:true
故:__proto__对象原型和原型对象prototype是等价的

4、constructor构造函数

我们来尝试分别打印一下原型对象和对象原型

console.log(Student.prototype);
console.log(xl.__proto__);

JavaScript高级 构造函数与原型篇_第4张图片

不难发现,它们都有一个属性叫constructor属性,这个属性指向构造函数本身。constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。


 一般情况下,对象的方法都在构造函数的原型对象中设置。当给构造函数添加多个方法时,可以采用对象的方式。

5、构造函数、实例、原型对象三者之间的关系

JavaScript高级 构造函数与原型篇_第5张图片

6、原型链(JavaScript的成员查找机制)

  1. 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  2. 如果没有就查找它的原型(也就是 __proto__指向的 prototype原型对象)。
  3. 如果还没有就查找原型对象的原型(Object的原型对象)。
  4. 依此类推一直找到 Object 为止(null)。

__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。
JavaScript高级 构造函数与原型篇_第6张图片

针对原型链的练习,加深印象



  
    
    
    
    原型链
  
  
    
  

你可能感兴趣的:(javascript,开发语言,ecmascript)