js原型链以及对象的类与继承

原型链

**定义:**按照JS引擎的分析方式,在访问一个实例的属性的时候,现在实例本身中找,如果没找到就去它的原型中找,还没找到就再往上找,直到找到。这就是原型链。

img

  • 实例的_protpo_指向的是原型对象。
  • 实例的构造函数的prototype也是指向的原型对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BmXttn5y-1610412275756)(C:\Users\geqilin\AppData\Roaming\Typora\typora-user-images\1597286397572.png)]

4.类与继承

1.类的定义

//类的声明
var Animal = function () {
    this.name = 'Animal';
};
//第二种,Parent2为类的构造函数。
function Parent2 () {
    this.name = 'parent2';
    this.play = [1, 2, 3];
}
obj=new Parent2();

//ES6中类的声明
class Animal2 {
    constructor () {
        this.name = 'Animal2';
    }
} 

2.原型的属性和对象的属性

在实例的原型上添加一个方法,这个原型的所有实例便都有了这个方法。

1)原型属性相当于类属性,所有实例共享。

function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
};
var obj=new Parent3();
obj.prototype.play=[1,2,3,4,5];
//obj.play对象的属性
console.log(obj.play);//(3) [1, 2, 3]
//obj.__proto__.play访问原型的属性
console.log(obj.__proto__.play);//(5) [1, 2, 3, 4, 5]

2)只有创建一个实例对象才能访问到函数的原型属性。

function  a2(){this.name="lisi"}
undefined
a2
ƒ a2(){this.name="lisi"}
a2.prototype.a=2;
2
a2.a;
undefined
a2.__proto__;
ƒ () { [native code] }
var b=new a2();
undefined
b;
a2 {name: "lisi"}
name: "lisi"
__proto__:
a: 2
constructor: ƒ a2()
__proto__: Object

3.JS中的call()方法和apply()方法

作用:

都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向

语法:

如果不传参数则使用全局对象;

函数名.call(’想将目标函数this改成的值‘);
函数名.apply(’想将目标函数this改成的值‘);

相同点:二者实现的功能相同;

不同点:

add第二个参数为可变长数组,apply第二个参数为数组。

function add(c,d){
        return this.a + this.b + c + d;
    }
    
var s = {a:1, b:2};
    console.log(add.call(s,3,4)); // 1+2+3+4 = 10
    console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14 

4.Object.create

语法:

Object.create(proto[, propertiesObject])

参数

  • proto

    新创建对象的原型对象。

  • propertiesObject

    可选。如果没有指定为 undefined,则是要添加到新创建对象的不可枚举(默认)属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。

返回值:

一个新对象,带着指定的原型对象和属性。

注意:

如果propertiesObject参数是 null 或非原始包装对象,则抛出一个 TypeError 异常。

function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

// 继承一个类,第二个参数创建一个可写的,可枚举的,可配置的属性p
MyClass.prototype = Object.create(SuperClass.prototype, {
  p: {
    value: 42, 
    writable: true,
    enumerable: true,
    configurable: true 
  } 
// 混合其它
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定constructor
MyClass.prototype.constructor = MyClass;

MyClass.prototype.myMethod = function() {
     // do a thing
};

Object.assign 会把 OtherSuperClass原型上的函数拷贝到 MyClass原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。

5.继承

// Shape - 父类(superclass)
function Shape() {
  this.x = 0;
  this.y = 0;
}

// 父类的方法
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
};

// Rectangle - 子类(subclass)
function Rectangle() {
  Shape.call(this); // call super constructor.继承父类的非原型属性(普通属性)
}

// 子类续承父类
Rectangle.prototype = Object.create(Shape.prototype);//获取父类原型属性
//上一步继承了父类的原型对象所以构造器为父类的构造器,因此需要将构造器设置为自己的。
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('Is rect an instance of Rectangle?',
  rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
  rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值