js原型和继承

原型和继承

1、对象的几种创建方式

1.1字面量方式
var obj = {};//不常用

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

1.2普通的方式
var Person=new Object()
Person.name='lhy'
Person.age=18
Person.speak=function(){
  console.log('hello');
}
console.log(Person);

缺点:

  • 因为是基于 Object 基类创建,所以无法获知对象的具体类型
  • 初始化成员非常麻烦
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

这个方法是目前比较流行的方法,主流浏览器都支持

缺点:是太浪费内存,占用资源

1.4使用原型改造构造函数的方法

每一个构造函数都有一个 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,这里为true表示两个内存地址相同
//输出 李白 10 hello world
//杜甫 8 hello world

解决了占用资源过度的问题,核心语法是:Person.prototype.speak

静态成员和实例成员

function Person(name){
            this.name=name;//实例属性
            Person.count=0 //静态属性
        }
        var a1=new Person('lhy')
        console.log(c1.name);//这个的值是lhy
        console.log(c1.count);//这个是获取不到任何值的
        // 实例只能访问实例对象,是this添加的
        // 静态属性只能通过类名Person.count来进行访问

2、原型

2.1 prototype 与 proto

  • 构造函数有一个原型对象,通过 prototype 获取
  • 基于构造函数创建对象后,每个对象都有一个私有的 proto 属性,指向兑现的构造函数的原型对象
  • 基于上面两点,构造函数 prototype 属性与对象的 proto 属性指向的是同一个对象
function Person(name){
            this.name=name;//实例属性
        }
        console.log(Person.prototype); //值是一个对象,这个叫原型对象
        var c1=new Person() 
        console.log(c1.__proto__); //__proto__是对象原型
        var c2=new Person()
        console.log(c2.__proto__);
        // 三个的值是相同的

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

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

所以基于上面的解释得出
function Person(name){
            this.name=name;
        }
        var a1=new Person('lhy')
        console.log(Object.getPrototypeOf(a1));
        console.log(a1.__proto__);
//两者的输出结果是相同的

2.2 constructor构造函数

**介绍:**对象原型( proto)和构造函数(prototype)原型对象里面都有一个属性 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 原型链

  • 构造函数的prototype属性指向了构造函数原型对象
  • 实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象
  • 构造函数的原型对象的constructor属性指向了构造函数

prototype 、proto 和 constructor 关系

img

3、this的指向

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

4、继承

4.1 class方式

class 方式创建的类,可以非常轻松的实现继承,使用关键字(extends)就可以进行继承子类继承父类

4.2 call方法

  • call 可以调用函数
  • call 可以修改this的指向,使用call()的时候 参数一是修改后的this指向,参数2,参数3…使用逗号隔开连接
function Parent(name,age){
    console.log(this);
    this.name=name
    this.age=age
}
function Chinese(name,age,hukou){
    Parent.call(this)
    this.hukou=hukou
}
var f=new Parent('杜甫',18)
var c=new Chinese('李白',20,'河北保定')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值