美文网首页
面向对象与原型(二)

面向对象与原型(二)

作者: 一江碎月 | 来源:发表于2017-11-06 14:53 被阅读0次

楔子

问题

在 java 中,首先定义一个 class,然后 new 出该 class 的实例,那么无论 new 多少次,新出现的类永远都具有 class 中定义的属性。

但 js 中不一样,js 中为某个对象新添加的属性,不会出现在新对象中。如下:

var o1 = {}
o1.name = 'o1.name'

var o2 = {}
alert(o2.name)

首先为 o1 创建 name 属性,但这个属性并没有被带到 o2 中,如果 o2 也想具有与 o1 一样的属性,就需要将 o1 的属性定义全部重写一遍。这就导致了一个问题 想要创建一个类似的对象,就需要写很多重复代码

假设有对象 A,现在想创建一个跟 A 只有一个属性不同的对象 B。按上述思路,我们需要重新创建一个 B 对象,然后将 A 、B 对象共用的属性与方法赋值给 B,代码繁琐。

工厂方法模式

为解决上述问题,可以使用工厂方法模式。

function createObj(){
    var d = new Object();
    d.h='h';
    return d;
}

通过上述方法产生的对象都会具有 h 属性。但由于工厂方法具有封装性,外界使用者根本不知道产生的对象是哪一个类的实例,也无法修改返回对象对应的类,因此,使用者可能没办法调用某些类特有的方法。

例如使用 createObj 方法产生对象后, 想调用 getFullYear() 方法是不可能的。因此 Object 对象没有 getFullYear() 方法。如果想使用 getFullYear() 就需要改成如下代码:

function creatObj2(){
    var d = new Date();
    d.h='h';
    return d;
}

这会有几个问题:1,使用者不能修改工厂方法里的代码;2. 即使修改了,也没有办法保证工厂方法能兼容所有的类,类的个数无限,不可能为每一个类创建一个工厂方法。

构造函数

  1. 构造函数也是函数,也可以直接调用;每一个函数都可以转成构造函数,从而可以创建实例

  2. 与 new 关键字结合时,普通函数会转为构造函数,进而创建出一个对象,该类的类名就是构造函数的方法名

    var o = function(){
        this.age = arguments[0]; // this 指代的是新创建出来的对象
    }
    var oo = new o('age'); // 与 new 关键字结合,转为构造函数,进而创建一个实例
    alert(oo.age)
    alert(oo instanceof o) // true
    
    o('直接调用'); //直接调用时,this 指代的是 window
    alert(window.age+",from window") // 所以 window.age 输出的是 ‘直接调用’
    
  3. 由于 this 指代的是当前对象,所以在构造函数中的 this 指的就是新创建的对象

    function Demo(){
            this.m = function(){
            alert('this is m ')
        }
    }
    
    var o = new Object();
    Demo.call(o)
    o.m()
    

    如果不调用 Demo.call() 就没办法直接调用 o.m() ,因为 Object 类中没有方法名为 m 的方法。
    调用 call 方法后,相当于在 o 对象中运行了一次 Demo 方法,而其中的 this 指的就是 o 对象,所以 o 对象中已经具有了 m 方法。

  4. 与工厂方法相比,构造函数有如下优点:

    • 没有 new Object()

    • 直接将属性赋值给 this ,而不是赋值给一个 Object 对象

    • 不需要直接返回一个对象。

    • 返回的对象不但 instanceof Object ,而且还 instanceof 构造函数对应的类。

  5. 构造函数实质上与工厂方法一样,只不过 new Object() 与 return 语句是在后台进行。构造函数算是一个改良后的工厂方法

  6. 一般来说,构造函数首字母大写,而普通函数不需要。

相关文章

  • 面向对象与原型(二)

    楔子 问题 在 java 中,首先定义一个 class,然后 new 出该 class 的实例,那么无论 new ...

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

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

  • Javascript-高级篇之面向对象

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

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

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

  • JS 面向对象与原型(二)

    原型:创建的每个函数都有一个 prototype (原型) 属性,这个属性是一个指针,指向一个对象,而这个对象的用...

  • 面向对象:JavaScript

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

  • JavaScript之面向对象编程

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

  • 面向对象与原型

    对象的原型 每个对象都含有原型的引用,当查找属性时,若对象本身不具有该属性,则会查找原型上是否有该属性。对象的原型...

  • 面向对象与原型

    ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就是...

  • Js面向对象

    一、Js面向对象 二、Js原型及原型链 1、原型 JavaScript 的每个对象都继承另一个父级对象,父级对象称...

网友评论

      本文标题:面向对象与原型(二)

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