慎用 somefunction.prototype 分析

代码如下:

// code from jb51.net
function Person(name) {
this.Name = name;
}
Person.prototype.SayHello = function() {
alert('Hello, ' + this.Name);
}
Person.prototype.SayBye = function() {
alert('Goodbye, ' + this.Name);
}

不过,有的时候,为了书写以及维护的方便,我们会把公有方法的声明写到一个对象里,然后赋值给 Person.prototype,例如:


代码如下:

// code from jb51.net
function Person(name) {
this.Name = name;
}
Person.prototype = {
SayHello: function() {
alert('Hello, ' + this.Name);
},
SayBye: function() {
alert('Goodbye, ' + this.Name);
}
}

使用这种方式,在这个类具有大量公有方法的时候,就不需要维护许多的 Person 标识符,如果某一天这个类的名字需要改变,那么要改的地方只有两个,一个是 function 的声明,一个是 prototype 前面的标识符,如果是使用前一种方式的话,那么有多少个公有方法,就需要维护 N+1 个标识符了,虽然可以使用查找替换,但是从稳定上来说,查找替换可能会引起一些错误,这增加了维护的成本。

这种方式虽然给我们的维护增加了便利,但也引发了另外一个隐藏的问题,就是类的 constructor 属性丢失的问题。


代码如下:

// code from jb51.net
function Person1(name) {
this.Name = name;
}
Person1.prototype.SayHello = function() {
alert('Hello, ' + this.Name);
}
Person1.prototype.SayBye = function() {
alert('Goodbye, ' + this.Name);
}
// code from jb51.net
function Person2(name) {
this.Name = name;
}
Person2.prototype = {
SayHello: function() {
alert('Hello, ' + this.Name);
},
SayBye: function() {
alert('Goodbye, ' + this.Name);
}
}
alert(new Person1('Bill').constructor);
alert(new Person2('Steve').constructor);

运行上面的测试代码我们可以发现,Person1 的 constructor 属性为 Person1 类的构造函数,但是 Person2 的 constructor 属性却是 Object,那么在需要使用 constructor 属性来判断对象类型的时候,就会出现问题。
因此,在写 JavaScript 类的时候,如果不需要使用 constructor 属性来获取对象的类型,那么个人比较倾向于使用第二种写法,但是如果需要使用 constructor 属性以实现自己的反射机制或 GetType 函数等等,那么就要使用第一种写法。
当然,如果在实现自己反射机制或 GetType 函数时并不依赖 constructor 属性,那么两种写法都是可以的了,例如额外维护一个成员变量,用于标识自身的类型等。也可以使用一些现成的JS框架,有一些框架已经实现了JS中类的实现等,例如 js.class,这就看个人需要进行取舍了。

(0)

相关推荐

  • Function.prototype.bind用法示例

    复制代码 代码如下: //ECMAScript 5 Function.prototype.bind函数兼容处理 (function(){ if ( !Function.prototype.bind ) { //function(){}.bind Function.prototype.bind = function ( o, /*参数列表*/ ) { var self = this, boundArgs = Array.prototype.slice.call(arguments, 0); ret

  • function foo的原型与prototype属性解惑

    疑惑出自于: 复制代码 代码如下: function foo { this.name = 'foo'; } alert(foo.prototype === Function.prototype ); //false. 当时一直没想明白为啥foo的原型不是Function.prototype. 下面例子让我想当然的认为o.prototype === Function.prototype 应该为true的: 复制代码 代码如下: function foo() { this.name = 'foo';

  • Prototype Function对象 学习

    这个对象就是对function的一些扩充,最重要的当属bind方法,prototype的帮助文档上特意说了一句话:Prototype takes issue with only one aspect of functions: binding.其中wrap方法也很重要,在类继承机制里面就是利用wrap方法来调用父类的同名方法.argumentNames bind bindAsEventListener curry defer delay methodize wrap 复制代码 代码如下: //通

  • Function.prototype.call.apply结合用法分析示例

    昨天在网上看到一个很有意思的js面试题,就跟同事讨论了下,发现刚开始很绕最后豁然开朗,明白过来之后发现还是挺简单的,跟大家分享下! 题目如下:var a = Function.prototype.call.apply(function(a){return a;}, [0,4,3]);alert(a); 分析步骤如下: 1.将Function.prototype.call当成整体,call方法是由浏览器实现的本地方法,是函数类型的内部方法 var a = (Function.prototype.c

  • Function.prototype.apply()与Function.prototype.call()小结

    老是忘掉这两个东东的用下,写下来做个记录吧. 他们作用是一模一样的,只是传入的参数不一样 apply apply接受两个参数,第一个制定了函数体内this对象的指向,第二个参数为一个带下标的集合(可遍历对象),apply方法把这个集合中的元素作为参数传递给被调用的函数: var func = function(a, c, c){ alert([a,b,c]); //[1,2,3] } func.apply(null, [1,2,3]); call call传入的参数不固定,和apply相同的是,

  • 慎用 somefunction.prototype 分析

    复制代码 代码如下: // code from jb51.net function Person(name) { this.Name = name; } Person.prototype.SayHello = function() { alert('Hello, ' + this.Name); } Person.prototype.SayBye = function() { alert('Goodbye, ' + this.Name); } 不过,有的时候,为了书写以及维护的方便,我们会把公有方

  • jQuery.prototype.init选择器构造函数源码思路分析

    一.源码思路分析总结 概要: jQuery的核心思想可以简单概括为"查询和操作dom",今天主要是分析一下jQuery.prototype.init选择器构造函数,处理选择器函数中的参数: 这个函数的参数就是jQuery()===$()执行函数中的参数,可以先看我之前写的浅析jQuery基础框架一文,了解基础框架后,再看此文. 思路分析: 以下是几种jQuery的使用情况(用于查询dom),每种情况都返回一个选择器实例(习惯称jQuery对象(一个nodeList对象),该对象包含查询

  • Javascript Function.prototype.bind详细分析

      Function.prototype.bind分析 bind()方法会创建一个新的函数,成为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调取原函数. 实际使用中我们经常会碰到这样的问题: var name = "pig"; function Person(name){ this.name = name; this.getName = function

  • JS中prototype的用法实例分析

    本文实例讲述了JS中prototype的用法.分享给大家供大家参考.具体分析如下: JS中的phototype是JS中比较难理解的一个部分   本文基于下面几个知识点:   1 原型法设计模式 在.Net中可以使用clone()来实现原型法 原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展.我们称B的原型为A.   2 javascript的方法可以分为三类: a 类方法 b 对象方法 c 原型方法 例子如下: function People(name

  • Vue源码中要const _toStr = Object.prototype.toString的原因分析

    在vue的源码中,vue/src/shared/util.js文件中存放的是一些方法.其中作者用了Object.prototype.toString这个方法来判断类型,但是并没有直接用,而是单独保存在一个变量: const _toStr = Object.prototype.toString 那么为什么要这么做呢? 先说下判断类型.众所周知,typeof在判断对象时不能正确判断Null,并且不能识别出Array,但在判断基础类型时是没问题的.所以尤大也写了: export function is

  • js prototype深入理解及应用实例分析

    本文实例讲述了js prototype深入理解及应用.分享给大家供大家参考,具体如下: 上一篇讲了js的prototype概念,在这里回顾一下prototype的定义: prototype是函数的一个属性,并且是函数的原型对象.引用它的必然是函数,这个应该记住. 但是,很奇怪,各位看官,你有没有看过类似下面这样引用prototype的js代码: function func(){ var args = Array.prototype.slice.call(arguments, 1); return

  • Array.prototype 的泛型应用分析

    题目 请说明下面语句的输出: 复制代码 代码如下: x = {shift:[].shift}; x.shift(); console.info(x.length); 如果你回答正确,那么说明你已经了解 Array 函数的泛型应用.在理解这到题目之前,我 我们首先要了解数组(Array)的 shift 定义. MDC 中已经对相关的说明描述得非常的清楚 复制代码 代码如下: shift is intentionally generic; this method can be called or a

  • array.prototype.silce.call 理解分析

    Array.prototype.slice.call(thisArg[, arg1[, arg2[, ...]]])成员介绍: Array   数组对象 prototype [property]是javascript中对象的属性,用来返回对象的原型引用,可以动态的给此添加方法和属性,对象如array,object,或者用户定义的对象,详细请看这里 slice [Function]用原array对象,截取指定部分返回一个新的Array 对象,详细请看这里 call [Function]   cal

  • javascript中的prototype属性实例分析说明

    在Javascript中,一切都是对象,字符串是对象,数组是对象,变量是对象,函数也是对象,所以才会允许['a','b','c'].push('d');这样的操作存在.类本身也是一个对象,也可以定义属性和方法: 复制代码 代码如下: function Test(){}; Test.str = 'str'; Test.fun = function(){return 'fun';}; var r1 = Test.str; // str var r2 = Test.fun(); // fun var

随机推荐