javascript原型和继承

原型和继承

1.1对象的创建方式
1.1.1 字面量方式

var obj = {};

此种方式在主要用来创建 json 数据,一般不会用来创建对象

1.1.2 普通模式
基于 Object 创建

var Person=new Object()
Person.name='yhb'
Person.age=20
Person.speak=function(){
  console.log('hello');
}
console.log(Person);

缺点:

*因为是基于 Object 基类创建,所以无法获知对象的具体类型
*初始化成员非常麻烦
1.1.3 构造函数方式

function Person(name,age){
  this.name=name
  this.age=age
  this.speak=function(){
    console.log('hello world');
  }
}
var p1=new Person('李白',10)
console.log(p1); // Person

缺点:每个函数都会开辟一块新的内存,造成内存浪费

var p1=new Person('李白',10)
var p2=new Person('杜甫',8)
console.log(p1.speak===p2.speak); // false

解决方案:原型

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

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

function Person(name, age) {
     this.name = name;
     this.age = age;
 }
// 将方法定义到原型上
Person.prototype.speak = function () {
    console.log("hello world");
};
var p1 = new Person("李白", 10);
var p2 = new Person("杜甫", 8);
console.log(p1.speak === p2.speak); // true

1.2静态成员和实例成员
1.2.1实例成员
实例成员就是构造函数内部的成员 实例成员只能通过实例化的对象来访问,也就是说实例成员只跟每个对象实例有关,不同对象实例成员是没有任何关系的

function Star(uname, age) {
     this.uname = uname;
     this.age = age;
     this.sing = function() {
     console.log('我会唱歌');
    }
}
var lyf = new Star('李易峰', 18);
console.log(lyf.uname);//实例成员只能通过实例化的对象来访问

1.2.2静态成员
静态成员 在构造函数本身上添加的成员,与具体的对象无关

function Car(brand) {
    this.brand = brand;
    if (!Car.total) {
        Car.total = 0;
    }
    Car.total++;
}
var c1=new Car('五菱')
var c2=new Car('长安')
// 获取静态属性total
console.log(Car.total);

在这里插入图片描述
**

2. 原型

**

2.1 prototype 与 proto
首先厘清如下几个概念

1,构造函数有一个原型对象,通过 prototype 获取
2,基于构造函数创建对象后,每个对象都有一个私有的 proto 属性,指向兑现的构造函数的原型对象
3,基于上面两点,构造函数 prototype 属性与对象的 proto 属性指向的是同一个对象

4,__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype

5,遵循ECMAScript标准,someObject.[[Prototype]] 符号是用于指向 someObject 的原型。从 ECMAScript 6 开始,[[Prototype]] 可以通过 Object.getPrototypeOf() 和 Object.setPrototypeOf() 访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性 proto
在这里插入图片描述

2.2 constructor构造函数

对象原型( proto)和构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身
在这里插入图片描述
constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数如:

function Car(brand) {
            this.brand = brand // 实例属性            
        }

        Car.prototype = {
            constructor:Car,
            drive: function () {
                console.log('骑着我的小毛驴');
            },
            start: function () {
                console.log('start');
            },
            stop: function () {
                console.log('stop');
            },
            run: function () {
                console.log('run');
            }
        }
        console.log(Car.prototype)    
        var c1 = new Car()
        c1.drive()

2.3 原型链
​ 每一个实例对象又有一个 __proto__属性,指向的构造函数的原型对象,构造函数的原型对象也是一个对象,也有__proto__属性,这样一层一层往上找就形成了原型链。
2.4 构造函数实例和原型对象三角关系
在这里插入图片描述
2.5 原型链和成员的查找机制
任何对象都有原型对象,也就是prototype属性,任何原型对象也是一个对象,该对象就有__proto__属性,这样一层一层往上找,就形成了一条链,我们称此为原型链;

当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
如果还没有就查找原型对象的原型(Object的原型对象)。
依此类推一直找到 Object 为止(null)。
__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。

2.6 原型对象中this指向
构造函数中的this和原型对象的this,都指向我们new出来的实例对象

 * 1)在构造函数中,this 指代的是创建的构造函数的对象实例
         * 2)在构造函数的原型对象中,this 同样指代的是创建的构造函数的对象实例
         * 
         */ 
        function Car(bran) {
            this.brand = bran
            console.log(this);
        }
        Car.prototype.run=function(){
            console.log(this);
        }
        var c1 = new Car('五菱宏光')
        var c2 = new Car('长城皮卡')
        c1.run()
        c2.run()

2.7 通过原型为数组扩展内置方法
上面开发者自己定义的 Person、Dog、Car 等构造函数,目的是根据这个构造函数,创建对象,在程序中使用

JS 中有一些内置对象,比如 Array

Array 就是一个构造函数,所以我们以前创建数组时,可以使用如下方式

var arr=new Array()
Array.prototype.sum = function () {
        var sum = 0;
        this.forEach(function (item) {
          sum += item;
        });
        return sum
      };
      var arr = [1, 3, 5];
      console.log(arr.sum());;
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值