Javascript-6. 面向对象编程

目录

实例对象与new命令

不同与C++、Java基于类,JS是基于构造函数和原型链

构造函数

JS使用构造函数作为对象的模板,用于实例化对象,特点如下:

  • 内部使用this代表要生成的对象实例
  • 生成对象的时候,必须使用new命令

new

new的作用是执行构造函数,返回一个实例对象

var Vehicle=function(p){
    this.price=p;
}

var v=new Vehicle(10000);
v.price;    //10000
原理
  • 创建一个空对象,作为要返回的对象
  • 将这个空对象的原型[[Prototype]],指向构造函数的prototype属性
  • 将空对象赋给this关键字,开始执行函数内部的代码

如果构造函数内部有return语句,而且return返回一个对象,则new命令返回return指定的对象;否则返回this对象

target属性

如果当前函数是new命令调用的,则new.target指向当前函数,否则为undefined

function f(){
    console.log(new.target==f);
}

f();  //false
new f();    //true;
注意

如果调用构造函数时,没有使用new,构造函数会变成普通函数,this代表全局对象

var Vehicle=function(){
    this.price=1000;
}

var v=Vehicle();
v;  //undefined
price;  //price成为全局变量

如果使用严格模式,在第一行加上’use strict’,一旦忘记使用new命令,将会报错

this

在JS中,函数可以在不同的运行环境(对象)中执行,使用this能够在函数体内部获得当前的运行环境。this指明函数运行时的对象.

(对比:Java和C++只有类中的函数才使用this关键字)

var f1=function(){
    var x=100;
    console.log(x);
}

var f2=function(){
    var x=100;
    console.log(this.x);
}

var x=200;
f1();   //100
f2();   //200

上例中,f1没有加this关键词,输出的是函数作用域内的x;f2加上this关键词,输出的是全局环境的x

用法总结

  • 在方法中,this指的是所有者的对象
    var Student={
        name:'张三';
        describe:function(){
            console.log('I am '+this.name);
        }
    };
    
    var name='李四';
    Student.describe(); // '张三'
    var f=Student.describe;
    f();    // '李四'
    
  • 在构造函数中,this指的是创建的对象
  • 在函数中,this指的是全局对象。在严格模式下,为undefined
    function f1(){
        return this;
    }
    function f2(){
        'use strict';
        return this;
    }
    
    f1();    // [Object Window]
    f2();    // undefined
    
  • 在单独情况下,this指的是对象

绑定this的方法

  • call()
  • apply()
  • bind()

原型对象

函数有一个特定的属性:prototype,指向原型对象。原型对象的属性和方法对于该构造函数的实例对象是共享的。

调用构造函数创建实例对象时,实例对象内部的[[Prototype]]指针就会被赋值为构造函数的原型对象

方法

isPrototypeOf()

A.prototypeOf(B) :A为构造函数;B为实例对象

如果B的[[Prototype]]指向A.prototype,则返回true;否则返回false

getPrototypeOf()

Object.getPrototypeOf(A):A为实例对象

返回A的[[Prototype]]的值

setPrototypeOf()

Object.setPrototypeOf(A,B):A、B为实例对象

让A的[[Prototype]]指向B

原型层级

实例可以读取原型的值,但不能修改。如果添加一个与原型同名的属性,那就会在实例上创建这个属性,遮蔽住原型的属性

获取属性

  • for……in……:枚举所有可以遍历的属性,包括实例属性、原型属性。配合Object.hasOwnProperty(obj)可以遍历实例属性
  • Object.keys(obj):获取obj可枚举的实例属性,以字符串数组形式返回
  • Object.getOwnPropertyNames():获取所有实例属性,以字符串数组形式返回

继承

原型链

继承父类的属性和方法,作为公有属性和方法

子类需要覆盖父类的方法,或者增加父类没有的方法时,必须在原形赋值之后,再添加到原型上

问题:利用原型链继承的属性都是公有的,则不同实例对象的属性值都是一样的

盗用构造函数

利用原型链继承的属性在不同实例对象的属性值都是一样的,可以使用“盗用构造函数”解决

原理:在子类构造函数中调用父类的构造函数

问题:无法继承父类的原型定义的属性和方法。继承的方法无法重用

组合继承

属性使用“盗用构造函数”继承,这样继承的属性是私有的

方法使用“原型链”继承,使得继承的方法可以重用

// 第一步,子类继承父类的实例
function Rectangle() {
  Shape.call(this); // 调用父类构造函数
}
// 另一种写法
function Rectangle() {
  this.base = Shape;
  this.base();
}

// 第二步,子类继承父类的原型
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

Object相关方法

原型相关

  • Object.getPrototypeOf()
  • Object.setPrototypeof()
  • Object.prototype.isPrototypeof()

属性相关

  • Object.getOwnPropertyNames()
  • Object.prototype.hasOwnProperty()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值