JavaScript中几个重要的属性(this、constructor、prototype)介绍


Posted in Javascript onMay 19, 2013

this
this表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window; 如果在函数中使用this,则this指代什么是根据运行时此函数在什么对象上被调用。 我们还可以使用apply和call两个全局方法来改变函数中this的具体指向。
先看一个在全局作用范围内使用this的例子:

<script type=> 
console.log( === window); 
console.log(window.alert === .alert); 
console.log(.parseInt(, 10)); 
</script>

函数中的this是在运行时决定的,而不是函数定义时,如下:
foo() { 
console.log(.fruit); 
} 
fruit = ; 
foo(); 
pack = { 
fruit: , 
foo: foo 
}; 
pack.foo();

全局函数apply和call可以用来改变函数中this的指向,如下:
foo() { 
console.log(.fruit); 
} 
fruit = ; 
pack = { 
fruit: 
}; 
foo.apply(window); 
foo.apply(pack);

注:apply和call两个函数的作用相同,唯一的区别是两个函数的参数定义不同
因为在JavaScript中函数也是对象,所以我们可以看到如下有趣的例子:
foo() { 
( === window) { 
console.log(); 
} 
} 
foo.boo = () { 
( === foo) { 
console.log(); 
} ( === window) { 
console.log(); 
} 
}; 
foo(); 
foo.boo(); 
foo.boo.apply(window);

prototype
prototype本质上还是一个JavaScript对象。 并且每个函数都有一个默认的prototype属性。
如果这个函数被用在创建自定义对象的场景中,我们称这个函数为构造函数。 比如下面一个简单的场景:
Person(name) { 
.name = name; 
} 
Person.prototype = { 
getName: () { 
.name; 
} 
} 
zhang = Person(); 
console.log(zhang.getName());

作为类比,我们考虑下JavaScript中的数据类型 - 字符串(String)、数字(Number)、数组(Array)、对象(Object)、日期(Date)等。 我们有理由相信,在JavaScript内部这些类型都是作为构造函数来实现的,比如:
Array() {
}
arr1 = Array(1, 56, 34, 12);
arr2 = [1, 56, 34, 12];
同时对数组操作的很多方法(比如concat、join、push)应该也是在prototype属性中定义的。
实际上,JavaScript所有的固有数据类型都具有只读的prototype属性(这是可以理解的:因为如果修改了这些类型的prototype属性,则哪些预定义的方法就消失了), 但是我们可以向其中添加自己的扩展方法。
Array.prototype.min = () {
min = [0];
( i = 1; i < .length; i++) {
([i] < min) {
min = [i];
}
}
min;
};
console.log([1, 56, 34, 12].min());
注意:这里有一个陷阱,向Array的原型中添加扩展方法后,当使用for-in循环数组时,这个扩展方法也会被循环出来。
下面的代码说明这一点(假设已经向Array的原型中扩展了min方法):
arr = [1, 56, 34, 12];
total = 0;
( i arr) {
total += parseInt(arr[i], 10);
}
console.log(total);
解决方法也很简单:
arr = [1, 56, 34, 12];
total = 0;
( i arr) {
(arr.hasOwnProperty(i)) {
total += parseInt(arr[i], 10);
}
}
console.log(total);
constructor
constructor始终指向创建当前对象的构造函数。比如下面例子:
arr = [1, 56, 34, 12]; 
console.log(arr.constructor === Array); 
Foo = () { }; 
console.log(Foo.constructor === Function); 
obj = Foo(); 
console.log(obj.constructor === Foo); 
console.log(obj.constructor.constructor === Function);

但是当constructor遇到prototype时,有趣的事情就发生了。
我们知道每个函数都有一个默认的属性prototype,而这个prototype的constructor默认指向这个函数。如下例所示:
Person(name) { 
.name = name; 
}; 
Person.prototype.getName = () { 
.name; 
}; 
p = Person(); 
console.log(p.constructor === Person); 
console.log(Person.prototype.constructor === Person); 
console.log(p.constructor.prototype.constructor === Person);

当时当我们重新定义函数的prototype时(注意:和上例的区别,这里不是修改而是覆盖), constructor的行为就有点奇怪了,如下示例:
Person(name) { 
.name = name; 
}; 
Person.prototype = { 
getName: () { 
.name; 
} 
}; 
p = Person(); 
console.log(p.constructor === Person); 
console.log(Person.prototype.constructor === Person); 
console.log(p.constructor.prototype.constructor === Person);

为什么呢?
原来是因为覆盖Person.prototype时,等价于进行如下代码操作:
Person.prototype = Object({ 
getName: () { 
.name; 
} 
});

而constructor始终指向创建自身的构造函数,所以此时Person.prototype.constructor === Object,即是:
Person(name) { 
.name = name; 
}; 
Person.prototype = { 
getName: () { 
.name; 
} 
}; 
p = Person(); 
console.log(p.constructor === Object); 
console.log(Person.prototype.constructor === Object); 
console.log(p.constructor.prototype.constructor === Object);

怎么修正这种问题呢?方法也很简单,重新覆盖Person.prototype.constructor即可:
Person(name) { 
.name = name; 
}; 
Person.prototype = Object({ 
getName: () { 
.name; 
} 
}); 
Person.prototype.constructor = Person; 
p = Person(); 
console.log(p.constructor === Person); 
console.log(Person.prototype.constructor === Person); 
console.log(p.constructor.prototype.constructor === Person);
Javascript 相关文章推荐
JS是否可以跨文件同时控制多个iframe页面的应用技巧
Dec 16 Javascript
jQuery ui 1.7更新小结
Aug 15 Javascript
Jquery知识点二 jquery下对数组的操作
Jan 15 Javascript
解析Jquery取得iframe中元素的几种方法
Jul 04 Javascript
在firefox和Chrome下关闭浏览器窗口无效的解决方法
Jan 16 Javascript
原生js仿jq判断当前浏览器是否为ie,精确到ie6~8
Aug 30 Javascript
JavaScript输出当前时间Unix时间戳的方法
Apr 06 Javascript
Linux下为Node.js程序配置MySQL或Oracle数据库的方法
Mar 19 Javascript
浅析JavaScript中命名空间namespace模式
Jun 22 Javascript
JavaScript prototype属性详解
Oct 25 Javascript
vue项目中使用ueditor的实例讲解
Mar 05 Javascript
Angular如何在应用初始化时运行代码详解
Jun 11 Javascript
js函数中onmousedown和onclick的区别和联系探讨
May 19 #Javascript
下拉菜单点击实现连接跳转功能的js代码
May 19 #Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
May 19 #Javascript
固定背景实现的背景滚动特效示例分享
May 19 #Javascript
Jquery实现鼠标移上弹出提示框、移出消失思路及代码
May 19 #Javascript
扩展js对象数组的OrderByAsc和OrderByDesc方法实现思路
May 17 #Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
May 17 #Javascript
You might like
PHP循环输出指定目录下的所有文件和文件夹路径例子(简单实用)
2014/05/10 PHP
Jquery 最近浏览过的商品的功能实现代码
2010/05/14 Javascript
javascript实现上传图片并预览的效果实现代码
2011/04/11 Javascript
EASYUI TREEGRID异步加载数据实现方法
2012/08/22 Javascript
For循环中分号隔开的3部分的执行顺序探讨
2014/05/27 Javascript
jQuery插件开发详细教程
2014/06/06 Javascript
js单独获取一个checkbox看其是否被选中
2014/09/22 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
2015/05/14 Javascript
js实现的动画导航菜单效果代码
2015/09/10 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
2020/08/27 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
javascript实现简单的on事件绑定
2016/08/23 Javascript
angularjs指令之绑定策略(@、=、&amp;)
2017/04/13 Javascript
jQuery选择器之表单元素选择器详解
2017/09/19 jQuery
vue 移动端适配方案详解
2018/11/15 Javascript
让 babel webpack vue 配置文件支持智能提示的方法
2019/06/22 Javascript
Vue 动态路由的实现及 Springsecurity 按钮级别的权限控制
2019/09/05 Javascript
JavaScript canvas实现雪花随机动态飘落
2020/02/08 Javascript
Vue 中使用 typescript的方法详解
2020/02/17 Javascript
js实现小时钟效果
2020/03/25 Javascript
vue 监听窗口变化对页面部分元素重新渲染操作
2020/07/28 Javascript
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
pytorch模型预测结果与ndarray互转方式
2020/01/15 Python
python打印文件的前几行或最后几行教程
2020/02/13 Python
基于Tensorflow的MNIST手写数字识别分类
2020/06/17 Python
Python collections.defaultdict模块用法详解
2020/06/18 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
2021/02/02 Python
测试工程师岗位职责
2013/11/28 职场文书
大学自主招生自荐信范文
2014/02/26 职场文书
希特勒经典演讲稿
2014/05/19 职场文书
导游词开场白
2015/01/31 职场文书
特岗教师个人总结
2015/02/10 职场文书