在js语言规范中并不存在方法这一概念,方便起见,将作为对象属性的函数成为方法
this引用的规则
a.在最外层代码中,this引用的是全局对象
b.在函数内,this引用根据函数调用方式不同而不同
函数内部的this引用 见下表

函数的调用方式

this引用的引用对象

构造函数调用

所生成的对象

方法调用

接收方对象

apply或call调用

由apply或call的参数指定的对象

其它方式调用

全局对象

接收方对象是这样一种对象
通过点运算符或者中括号运算符调用对象方法时,在运算符左侧所指定的对象
下面是一个关于方法和接收方对象的具体实例

<script>
var obj={
x:3,
doit:function(){
p("method is called: "+this.x);
}
};
obj.doit();//对象obj是接收方对象 doit是方法
obj['doit']();//对象obj是接收方对象 doit是方法
//结果一样 method is called: 3
</script>

this引用应注意的点
this的引用的引用对象会随着方法的调用方式不同而不同

<script>
var obj={
x:3,
doit:function(){
p("method is called: "+this.x);
}
};
var fn=obj.doit;//将obj.doit引用的Function对象赋值给全局变量
fn();//method is called: undefined 函数内的this引用引用了全局变量
var x=5;
fn();//method is called: 5
var obj2={x:4,doit2:fn};//将obj的方法(Function对象的引用)赋值给了另一个对象obj2的属性
obj2.doit2();//method is called: 4 方法内的this引用引用了对象obj2
</script>
<script>
var obj={
x:3,
doit:function(){
p("doit is called "+this.x);this.doit2();
},
doit2:function(){
p("doit2 is called "+this.x);
}
};
obj.doit();
//doit is called 3
//doit2 is called 3
//如果将doit2前面的this去掉,则会查找全局里的doit2 嵌套的函数将按照作用域顺序由内到外的顺序查找
</script>

apply与call
在Function对象中包含apply和call这两种方法,通过他们调用的函数的this引用可以指向任意的特定对象,也就是他们可以
显式指定接收方对象

<script>
function f(a){
p(this.x+":"+a);
}
var obj={x:4};
f.apply(obj,[2]); //4 通过apply调用f函数内部this指向了obj
f.call(obj,2); //4 通过call调用f函数内部this指向了obj
var obj={
x:3,
doit:function(){
p("method is called:"+this.x);
}
};
var obj2={x:4};
obj.doit.apply(obj2);//method is called:4
p(Math.max(4,5,1,2));
var arr=[1,3,2,0,99];
var mx=Math.max.apply(null,arr);//没提供第一个参数 则global对象将被用作ths.obj
p(mx);//99
</script>

原型继承
形式上的理解
类名.prototype.方法名=function(参数){方法体}

<script>
function Myclass(x,y){
this.x=x;
this.y=y;
this.say=function(){
p(this.x+":"+this.y);
}
}
Myclass.prototype.show=function(){
p(this.x,this.y);
}
var obj1=new Myclass(1,2);
obj1.show();
p('show' in obj1);//true
p(obj1.hasOwnProperty('show')) //false
p(obj1.hasOwnProperty('say')); //true
p('show' in Myclass);//false
p("say" in Myclass);//false
p(typeof Myclass);//function
</script>

原型链
原型继承支持一种称为原型链的功能,使用原型链有2个前提
a.所有的函数(对象)都具有名为prototype的属性(prototype属性所引用的对象则称为prototype对象)
【对象实例 如上代码中的obj1没有prototype属性】

<script>
p( 'prototype' in obj1);//false
p('__proto__' in obj1);//true
p('prototype' in Myclass);//true
p("__proto__" in Myclass);//true
</script>

b.所有的对象都含有一个(隐藏的)链接,用以指向在对象生成过程中所使用的构造函数(Function对象)的prototype对象b.所有的对象都含有一个(隐藏的)链接,用以指向在对象生成过程中所使用的构造函数(Function对象)的prototype对象

<script>
p(obj1.__proto__===Myclass.prototype);//true
p(Myclass.__proto__);// function Empty() {}
p(obj1.prototype);//undefined
p('x' in Myclass);//false </script>

对象(类的实例)对属性的读取 查找顺序
1.对象自身的属性(通过实例化类获取的属性)
2.隐式链接所引用的对象(即构造函数的prototype对象)的属性 (obj1.__proto__=Myclass.prototype)
3.第二项中的对象的隐式链接所引用的对象的属性
4.反复按照第三步的规则查找直至全部查找完毕(查找的终点是Object.prototype对象)

当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样的一些代码
this.prototype={constructor:this}
新函数的对象被赋予一个prototype属性,他的值是包含constructor属性且属性值为该新函数的对象,这个prototype对象是存放继承特征的地方,
因为javascript语言没有提供一种方法去确定哪个函数是打算用来做构造器的,所以每个函数都会得到一个prototype对象
constructor没什么用
当采用构造器调用模式,即用new去调用一个函数,函数执行方式将发生改变
如果new 运算符是一个方法而不是一个运算符,它可能会这样执行

<script>
function a(){ }
p(a.prototype); //[object Object]
p(a.prototype.constructor); //function a(){ }
p(a.prototype.__proto__==Function.prototype);//false
p(a.prototype.__proto__==Object.prototype);//true p('method' in Function);//false
//伪代码
Function.method('new',function(){
//创建一个新对象,它继承自构造器函数的原型对象
var that=Object.create(this.prototype);
//调用构造器函数,绑定 this到新对象上
var other=this.apply(that,arguments);
//如果它的 返回值不是一个对象,就返回该新对象
return (typeof other==='object' && other)||that;
});
</script>

js方法和原型继承(一)的更多相关文章

  1. JS中的原型继承机制

    转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很 ...

  2. 关于js的对象原型继承(一)

    javascript中,对象的继承是通过原型去继承. 可以这样理解:js中的对象,包含的除了属性和方法,还有一个最基本的原型__proto__对象.这个原型__proto__指向谁,这个对象就继承谁. ...

  3. JS中的原型继承和多重继承

    概念:1原型继承是创建新类型对象----子类型,子类型基于父类型,子类型拥有父类型所有的属性和方法(从父类型继承得到),然后修改其中的部分内容或者添加新的内容.继承最好在子类型模型可以被视为父类型对象 ...

  4. 关于js的对象原型继承(二)

    本章讨论使用new一个构造函数来创建一个对象. 前期知识点说明: 1.prototype是函数的一个属性,每个函数都有一个prototype属性.这个属性是一个指针,指向一个对象.它是显示修改对象的原 ...

  5. js中的原型继承

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. JS 原型继承的几种方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  8. [转]Javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...

  9. js 继承 对象方法与原型方法

    js函数式编程确实比很多强语言使用灵活得多,今天抽了点时间玩下类与对象方法调用优先级别,顺便回顾下继承 暂时把原型引用写成继承 先看看简单的两个继承 var Parent = function(){} ...

随机推荐

  1. iOS 进入后台的处理

    当App进入后台时(按下Home键), App会被系统暂停, 所有的程序逻辑都会停止, App还是驻留内存中, 除非被用户强制退出, 或者被系统kill掉(为了保证正在前台运行的App有足够的内存, ...

  2. iOS 模态视图

    模态视图不是专门的某个类,而是通过视图控制器的presentViewController方法弹出的视图,我们称为模态视图. 模态视图出现的场景一般是临时弹出的窗口,譬如:登录窗口: 模态视图弹出时通过 ...

  3. Cannot merge new index 67361 into a non-jumbo instruction

    升级Android ADT 后项目出现如题错误. https://groups.google.com/forum/?fromgroups=#!topic/adt-dev/tuLXN9GkVas jus ...

  4. Arch-Linux-添加中文字体

    代码下载: Arch-Linux-添加中文字体.txt

  5. Redis附加功能之Redis流水线pipeline

    流水线功能的目的:通过减少客户端与服务器之间的通信次数来提高程序的执行效率. 一.通信 在一般情况下, 用户每执行一个 Redis 命令,客户端与服务器都需要进行一次通信:客户端会将命令请求发送给服务 ...

  6. RequireJS API

    可以找到许多的解读,但是原文总是最重要的,也是最正宗的说明,直接访问 RequireJS 有时不太方便,这里将 RequireJS 2.0 API 的原文转载到博客园,方便查看. This is th ...

  7. TCP/IP详解学习笔记(3)-- IP:网际协议

    1.概述      IP是TCP/IP协议族中最为核心的协议.所有的TCP,UDP,ICMP,IGMP数据都以IP数据报格式传输.      IP提供不可靠,无连接的数据报传送服务. 不可靠:它不能保 ...

  8. 使用CORS:跨域两三事

    本文为译文. 简介 APIS是可以将富网页应用串连在一起的线程.但是这个应用难以转给浏览器,跨域请求技术的选择被限制了,类似JSONP(由于安全考虑,使用会被限制),或者配置代理(设置和维护都比较头痛 ...

  9. 在VS2012中采用C++中调用DLL中的函数 (4)

    这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人 ...

  10. Leetcode008. String to Integer (atoi)

    /* improvement on dealing with overflow accroding to this: * https://discuss.leetcode.com/topic/5745 ...