美文网首页
4、原型和面向对象

4、原型和面向对象

作者: Elevens_regret | 来源:发表于2017-07-14 11:16 被阅读0次

实例化和原型

在JavaScript中,使用原型定义的属性和功能会自动应用到对象的实例上,一但进行了定义,原型的属性就会变成实例化对象的属性。所有函数初始化的时候都有一个prototype属性表示原型。

// 定义一个函数
function A() {}

// 在其原型上添加属性
A.prototype.go = function () {return true;};

// 将函数赋值给变量,空函数无返回值
var a1 = A();
console.log(a1);  // undefined

// 将函数作为构造器进行实例化赋值给变量
var a2 = new A();

// 变量成为一个实例
console.log(a2); // A {}

// 该实例继承了函数原型上的属性
console.log(a2.go()); // true

使用new操作符将函数作为构造器进行调用时,其上下文会被定义为新对象实例。这就表明,在构造器函数内部,可以使用this参数初始化值。在构造器内的绑定操作优先级会高于在原型上的绑定操作优先级,因为构造器的this上下文指的是实例自身。

// 使用同样的名称为构造器和原型添加属性
function A() {
    this.x=1;
}
A.prototype.x = 2;

// 实例继承属性时,构造器本身的属性会覆盖原型上的属性
var a1 = new A();
console.log(a1.x);  // 1

原型的改变会影响其构造器已经创建的实例对象。

// 创建构造函数并实例化
function A() {}
var a1 = new A();

// 改变其原型,已经实例化的对象上继承的属性也会被修改
A.prototype.x = 1;
console.log(a1.x);

每个JavaScript对象都有一个隐式属性constructor,该属性引用的是创建该对象的构造器。

function A() {}
var a1 = new A();
A.prototype.x = 1;
// 使用a1.constructor.prototype.x可以访问到原型上的x属性,证明了原型是实时附加在对象上的,所以在创建实力之后,更改原型也会生效。
console.log(a1.constructor.prototype.x);  // 1

查找属性时,首先查找对象自身,如果没有找到,再查找构造器的原型。

function A() {
    this.x=1;
    this.y=2;
}
var a1 = new A();
A.prototype.y=1;
// 实例化的对象a1已经具有了y属性,即使在实例化之后再为构造器的原型添加新的y属性,也不会覆盖实力中的原来的y属性。
console.log(a1.y);  // 2

利用constructor属性,可以在不知道原有构造器的情况下,利用已有的实例来创建新的实例。

function A() {}
var a1 = new A();
var a2 = new a1.constructor();
// a1与a2指向的不是同一个实例
console.log(a1 !== a2); // true

疑难陷阱

扩展原生Object.prototype时,所有对象都会接受这些额外的属性。当我们遍历对象的属性时,这些额外的属性也会被遍历。

// 为原生Object.prototype添加keys方法,返回一个属性名组成的数组。
Object.prototype.keys=function () {
    var key = [];
    for(var p in this){
        key.push(p);
    }
    return key;
};
var obj = {
    a:1,
    b:2,
    c:3
};
// keys方法本身被继承,也成为了实例obj的属性之一
console.log(obj.keys());  // ["a", "b", "c", "keys"]

使用hasOwnProperty()方法可以判断属性是实例自身的,还是继承自原型的

Object.prototype.keys=function () {
    var key = [];
    for(var p in this){
        // 判断属性是来自实例自身还是继承自原型
        if(this.hasOwnProperty(p)){
            key.push(p);
        }
    }
    return key;
};
var obj = {
    a:1,
    b:2,
    c:3
};
console.log(obj.keys()); // ["a", "b", "c"]

相关文章

  • 1.web前端基础储备之—js的面向对象风格以及原型和原型链

    javascript是面向对象风格,基于原型的语言。 目标:了解js面向对象和原型原型链的关系 面向对象(OOP)...

  • 介绍js中的原型

    原型 编程语言对面向对象的实现主流的有两种方式:基于类的面向对象和基于原型的面向对象。 基于类的面向对象 典型的语...

  • Javascript-高级篇之面向对象

    面向对象 基于原型的面向对象 基于原型的面向对象方式中,对象(object)则是依靠构造器(constructor...

  • lesson 5 面向对象及原型链 2021-04-29

    课程标题 面向对象及原型链 课程目标 面向对象思想 原型及原型链 继承 知识点 面向对象思想 原型链的指向 new...

  • 面向对象:JavaScript

    面向对象 面向对象组成 this指向 第一个面向对象 第一个面向对象加强版 第一个面向对象(this) 原型 原型...

  • 面向对象和原型

    1. OOP 指什么?有哪些特性? OOP: Object-oriented programming的缩写,即面向...

  • JavaScript之面向对象编程

    五、面向对象编程 目录:面向对象原型继承、面向对象class继承(ES6引入的) 1.面向对象原型继承 类:模板 ...

  • JS原型理解

    原型链是整个JS面向对象的基础在理解原型链之前先来谈谈JS创建对象的几种方式 可以看到输出了4个对象,a1和a2看...

  • 面向对象 原型和原型链

    什么是对象:内存中集中存储多个数据或函数的存储空间,再起一个名字对象是程序中描述现实中一个具体事务的属性和功能的结...

  • 2018-06-27

    JavaScript(面向对象+原型理解+继承+作用域链和闭包+this使用总结) 一、面向对象 1、什么是面向对...

网友评论

      本文标题:4、原型和面向对象

      本文链接:https://www.haomeiwen.com/subject/baxgcxtx.html