蝴蝶书中有一个method方法,用来给函数定义方法。看了之后,想着能不能给对象也定义方法呢?、

下面的代码可以实现给函数定义方法:

 //Function method
Function.prototype.method = function (name,func) {
this.prototype[name] = func;
return this;
}

在实现给对象定义方法的过程中,我遇到了一些问题,对象是没有prototype的。

经过思考,用下面的方法实现了给对象定义方法的功能,但是比较繁琐:

//Object method
Object.prototype.method = function (name,func) {
Object.prototype[name] = func; //不能用this,因为a没有prototype属性
return this;
}
//该方法的缺点是,一旦给某对象定义了方法,所有对象都将拥有该方法。

关于prototype和__proto__的思考:

var Person = function(arg1,arg2,...){};
var p = new Person();

等价于(某些情况下):

 var p={};  //也就是说,初始化一个对象p。
p.__proto__=Person.prototype;
Person.call(p,arg1,arg2,...); //也就是说构造p,也可以称之为初始化p(没有这一步,p是空的)。

其中:
p.__proto__ == Person.prototype;
Person.prototype:
Object {constructor: function}
函数Person的prototype是Person的一个属性,该属性是个对象,这个对象是p的原型。。

另外,由于 Person.call(p,arg1,arg2,...)构造p

使得p.construtor === Person();

我们生成一个Object和一个Function的来探寻这些内容的关系:
var a = new Object();
var b = new Function();

a.__proto__ == Object.prototype;
b.__proto__ == Function.prototype;

低层次,以下3个指向同一内容。
function () { [native code] }
1、 Function.prototype
2、 Object.__proto__
3、 Function.__proto__

高层次,以下4个指向同一内容。
Object {__defineGetter__: function, __defineSetter__: function, hasOwnProperty: function, __lookupGetter__: function, __lookupSetter__: function…}
1、 Object.prototype
2、 Function.prototype.__proto__
3、 Object.__proto__.__proto__
4、 Function.__proto__.__proto__
所以只有Function method,不定义Object method我们也照样会看到Object.method;
但是对于

var a = new Object();

Object并不是a的原型,所以a也不存在method方法。a的原型在高层次。
此时,我们为Object.prototype定义method方法,这是a的上级原型链,a就有了method方法.

注意:
既然Object method层次更高,就算没有Function method也无所谓。但是这可能涉及安全性问题。
如果既有Function method又有Object method
我们给Function添加method方法时,会调用Function method(从低向高查找method)
我们给Object添加method方法时,会调用Object method

最后一个例子:

var arr = new Array();
arr.__proto__ === Array.prototype;
//true
arr.constructor === Array;
//true
arr.__proto__ === arr.constructor.prototype;
//true

给对象和函数添加method方法的更多相关文章

  1. 你会如何给全局对象添加toString()方法

    首先,在讨论如何给所有方法window对象添加toString方法的时候,我们先来说说window的对象继承与对象实例,以及构造函数的this指针,还有变量的提升与方法的调用方式,最终一探window ...

  2. JavaScript函数之实际参数对象(arguments) / callee属性 / caller属性 / 递归调用 / 获取函数名称的方法

    函数的作用域:调用对象 JavaScript中函数的主体是在局部作用域中执行的,该作用域不同于全局作用域.这个新的作用域是通过将调用对象添加到作用域链的头部而创建的(没怎么理解这句话,有理解的亲可以留 ...

  3. 设计模式---对象创建模式之工厂方法模式(Factory Method)

    前提:“对象创建”模式 通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式(表现最为突出) 工 ...

  4. RegisterUserFunc为测试对象添加新方法或重写已有方法

    QTP中为了提高扩展性,提供了一个为测试对象添加一个新的自定义方法,或者重写测试对象已有的方法的函数RegisterUserFunc,在此给大家分享一下. RegisterUserFunc:为测试对象 ...

  5. jQuery源码06-jQuery = function(){};给JQ对象,添加一些方法和属性,extend : JQ的继承方法,jQuery.extend()

    /*! * Includes Sizzle.js 选择器,独立的库 * http://sizzlejs.com/ */ (function( window, undefined ) { //" ...

  6. 275 原型与原型链:显式原型prototype ,隐式原型__proto__,隐式原型链,原型链_属性问题,给原型对象添加属性/方法

    1.所有函数都有一个特别的属性 prototype : 显式原型属性 [普通构造函数的实例对象没有prototype 属性,构造函数有__proto__属性,原型对象有__proto__属性 ] 2. ...

  7. 在Function对象上扩展method方法

    ;(function() { /** * 在Function对象上扩展method方法 * @param {String} name 扩展的方法名称 * @param {Function} callb ...

  8. C++11用于计算函数对象返回类型的统一方法

    [C++11用于计算函数对象返回类型的统一方法] 模板 std::result_of 被TR1 引进且被 C++11 所采纳,可允许我们决定和使用一个仿函数其回返值的类别.底下,CalculusVer ...

  9. 函数对象的call()、apply() 方法区别

    函数对象的call().apply() 方法 函数作为对象提供了call(),apply() 方法,他们也可以用来调用函数,这两个方法都接受一个对象作为参数,用来指定本次调用时函数中this的指向: ...

随机推荐

  1. CVE-2017-7494:Linux Samba named pipe漏洞

    描述: 漏洞是由于代码中一个管道申请命令的判断导致的,可以通过构造特定请求执行上传的so文件. 漏洞影响了Samba 3.5.0 之后到4.6.4/4.5.10/4.4.14中间的所有版本. 测试: ...

  2. Shrio02 Realm作用、自定义简洁Realm、Realm实现类使用

    1 Realm简介 1.1 Realm作用 shiro最终是通过Realm获取安全数据的(如用户.角色.权限),也就是说认证或者授权都会通过Realm进行数据操作 1.2 Realm接口 1.2.1 ...

  3. java 实现模拟浏览器 访问网站

    一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等.所访问的这些页面 有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需 ...

  4. socket的protocal参数

    Documentation for socket() on Linux is split between various manpages including ip(7) that specifies ...

  5. Golang之interface(多态,类型断言)

    多态用法 package main //一种事物的多种形态,都可以按照统一的接口进行操作 //多态 import ( "fmt" "math/rand" &qu ...

  6. Golang作用域—坑

    先举个栗子,全局作用域变量,与 := 符号声明赋值新变量 package main import "fmt" var a = "GG" func main() ...

  7. marathon的高可用服务自动发现和负载均衡

    上一篇我们说谈了docker+zookeeper+mesos+marathon集群,本篇我们来谈谈marathon的集群和自动发现服务. marathon的服务自动发现和负载均衡有两种,1是mesos ...

  8. centos环境下登录mysql报 ERROR 1045 (28000)怎么解决

    centos环境下登录mysql报 ERROR 1045 (28000)怎么解决 新入手一台虚拟机,Centos7系列的操作系统,安装mysql后,执行连接出现了Mysql ERROR 1045 (2 ...

  9. Linux上编译hadoop-2.7.1的libhdfs.so和libhdfs.a

    hadoop提供了CMake来编译libhdfs,因此在编译之前需要先安装好CMake工具. 然后进入libhdfs的源代码目录,如:/data/hadoop-2.7.1-src/hadoop-hdf ...

  10. MFC中的主窗口修改标题

    MFC中的主窗口修改标题 如何去掉“无标题”1.在主程序中的InitInstance(): m_pMainWnd->SetWindowText("你要显示的东西如果不想显示置空就行&q ...