JavaScript prototype属性深入介绍

时间:2024-04-19 09:55:08 

每个函数创建时默认带有一个prototype属性,其中包含一个constructor属性,和一个指向Object对象的隐藏属性__proto__。constructor属性的值为该函数的对象。在一个函数前面加上new来调用,则会创建一个隐藏连接到该函数prototype成员的新对象(由__proto__属性来链接),同时函数的this将会被绑定到那个新对象上。
函数总是返回一个值;如果没有指定返回值,就返回undefined;如果当做构造函数来调用,且返回值不是对象,则返回this(该新对象);如果返回值是对象,则它作为构造函数是没有意义的!
[javascript]


function A(){
this.p = 'haha';
return {p:'heihei'};
}
var a = new A();
function A(){
this.p = 'haha';
return {p:'heihei'};
}
var a = new A();
alert(a.p);//显示'heihei',与var a = A();的效果一样


函数A内部直接调用一个函数B,B的this绑定到全局对象而不是其外部函数A,这是JS设计的一个错误。我们不得不用别的方式来解决这个问题,比如在A中用一个变量(通常是that)来保存A的this作用域的引用。
JS函数拥有一个length属性,表示函数定义时指定的形参的个数。
函数的arguments属性包含了调用函数时传入的所有参数,而不管函数的声明中是否定义了这些形参;arguments不是数组,只是一个“类似数组”的对象(在函数中运行arguments instanceof Array;返回false)。可以通过Array.prototype.slice.apply(arguments)将其转化为JS数组。
给JavaScript函数的原型增加方法(method),则所有的(构造)函数都可以用了!例如,可以给JS函数的构造者 Function 的原型增加一个method方法,则包括Object、Number等构造函数在内的所有函数都继承了该方法,这是很强大的:
[javascript]


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


这样,调用Object.method方法,就可以为所有的JS对象(包括Function对象)增加新的方法,调用Number.method方法,可以为所有的数值类型增加新的方法,下面一条就是这样的一个例子。 注意Object、Number等类型的对象此时并没有继承method方法。如果想达到这样的目的,可以运行类似下面的语句:
[javascript]


Object.method('method',Object.method);
Object.method('method',Object.method);


我们可以通过修改数值类型的原型,来给数值类型增加新的方法,这里我们借用上一条中提到的method方法来给Number的原型增加一个negative方法:
[javascript]


Number.method(negative,function(){
return 0–this;
})
Number.method(negative,function(){
return 0–this;
})


调用方法的时候稍微有一点绕。在JavaScript的语法中,数字后面直接跟点号,然后跟方法调用的语法是错误的;也就是说,3.negative()这样写是不对的。要想调用数值类型的方法,需要在数字后面加n个空格(n>=1),或者使用小括号将数字括起来,将其强制转化为表达式,然后再调用方法,或者干脆定义一个数值变量,也可以直接调用方法。也就是说,下面的写法都是正确的:
[javascript]
(3).negative();
3 .negative();
var n = 3; n.negative();
3['negative']();
(3).negative();
3 .negative();
var n = 3; n.negative();
3['negative']();
当使用函数表达式方法定义函数时,function后面的函数名可以用来递归地调用自己,并且这个名字不会被覆盖!我们来看下面的例子,
[javascript]


function a(n){
if(n>1)
return a(n-1)+1;
else
return 1;
};
function a(n){
if(n>1)
return a(n-1)+1;
else
return 1;
};


上述代码定义了一个函数a,并且其内部递归对自身进行了调用;现在我们用一个新的引用aa指向函数a,然后将原来的a改变,比如变为一个整数1,然后调用函数aa,如下面代码所示:
[javascript]


var aa = a;
a = 1;
aa(3);
var aa = a;
a = 1;
aa(3);


则控制台报错:TypeError: Property 'a' of object [object Window] is not a function;很显然,原来的递归函数已经被破坏了。关于这个问题,我们可以在函数a的内部,用arguments.callee.caller来代替a,或者用一个函数表达式来定义函数:
[javascript]


var b = function a(n){
if(n>1)
return a(n-1)+1;
else
return 1;
};
var bb = b;
a = 3;
bb(3);
var b = function a(n){
if(n>1)
return a(n-1)+1;
else
return 1;
};
var bb = b;
a = 3;
bb(3);


此时,bb函数能正确返回我们想要的结果。
为了提高JavaScript函数的封装性,我们可以定义函数化的构造器,下面是一个例子:


[javascript]
var funcCons = function(spec){
var that = {};
that.getName = function(){
return spec.name;
};
that.says = function(){
return spec.saying || '';
};
return that;
};
var myFunc = funcCons({name:'NearEast'});
var funcCons = function(spec){
var that = {};
that.getName = function(){
return spec.name;
};
that.says = function(){
return spec.saying || '';
};
return that;
};
var myFunc = funcCons({name:'NearEast'});


这样,我们可以在构造器中定义一些私有变量(如字典表)和函数,而不必把它们全部暴露在外面。

标签:JavaScript,prototype属性
0
投稿

猜你喜欢

  • MySQL密码正确却无法本地登录的解决方法

    2024-01-17 11:48:28
  • firefox 2正则表达式

    2008-08-25 19:15:00
  • 详解Python函数作用域的LEGB顺序

    2021-05-06 15:00:10
  • 基于django 的orm中非主键自增的实现方式

    2023-06-04 13:53:54
  • 谈谈网页设计中的字体应用 (4) 实战应用篇·下

    2009-11-24 13:13:00
  • 详解vue模拟加载更多功能(数据追加)

    2024-05-22 10:41:44
  • escape解决AJAX中文乱码的简单方法

    2008-10-23 14:32:00
  • Python中层次聚类的详细讲解

    2022-07-02 06:07:13
  • MYSQL数据库常用命令集合

    2009-02-26 16:01:00
  • 调整优化您的LAMP应用程序的5种简单方法

    2024-06-05 09:38:57
  • TorchVision Transforms API目标检测实例语义分割视频类

    2022-12-05 14:24:56
  • pandas删除某行或某列数据的实现示例

    2021-01-05 07:24:33
  • vite.config.js配置入门详解

    2024-04-30 10:38:25
  • python关于矩阵重复赋值覆盖问题的解决方法

    2021-12-11 03:07:17
  • sql无效字符 执行sql语句报错解决方案

    2023-06-24 19:47:45
  • Python OpenCV实现图像傅里叶变换

    2022-06-19 04:43:55
  • python 每天如何定时启动爬虫任务(实现方法分享)

    2022-11-28 21:14:35
  • 在Python的Django框架中simple-todo工具的简单使用

    2023-02-28 07:54:50
  • 详解Python中的各种函数的使用

    2022-03-23 22:09:52
  • Hadoop-3.1.2完全分布式环境搭建过程图文详解(Windows 10)

    2023-08-06 07:04:50
  • asp之家 网络编程 m.aspxhome.com