彻底搞清javascript中this, constructor, prototype
说起这三个属性,肯定有一些同学和我一样,初学js时非常困惑,头大,一脸的迷茫。今天就来给大家彻底解决这些担心受怕的问题。
先看this
this定义:
this就是函数赖以执行的对象。
分析这句话:
1. this是对象。
2. this依赖函数执行的上下文环境。
3. this存在函数中。
直接看例子:
alert(this); //在全局环境调用this, this指向window, 输出[Object window]
function Person(){
alert(this);
}
方式一:
Person(); // 全局环境用Person函数, this指向window, 输出[Object window]
方式二:
var obj = new Person(); //把Person当做构造函数, 实例化一个对象
//此时this指向了obj, 不再指向window, 输出[Object object]
function Person(){
alert(this.name); //此时无法判断this的身份
}
Person(); //this在全局环境中被调用, this.name == window.name, 输出了窗口的名字
var obj = new Person(); //this在obj环境下被调用, this.name == obj.name, 由于name没被赋值, 所以输出undefined
由此可以看出, 我们在阅读代码或者写代码时,看到某个函数中定义的this时, 还无法去判断那个this身份,必须找到它依赖执行的环境(对象)。
再回头看看this的定义,大家就清楚自然了。
再看constructor和prototype
constructor和prototype的关系非常密切。 constructor是一个对象的属性,这个属性存在在此对象的prototype中, 指向此对象的构造函数。 分析这句话:
1.constructor是一个对象属性。
2.constructor在prototype中
3.constructor指向构造函数 例子1: function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.getName = function(){
alert(this.name);
}
Person.prototype.getAge = function(){
alert(this.age);
}
var obj = new Person();
alert(obj.constructor == Person);// true
此种方式定义的prototype, constructor是隐藏的, 默认指向Person 例子2:
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype = {
getName: function(){
alert(this.name);
},
getAge: function(){
alert(this.age);
}
}
var obj = new Person();
alert(obj.constructor == Person);// false 为什么是false? 这种定义prototype, 是把prototype重写了, 覆盖了默认的constructor。
换句话说, 其实这种方式就是给属性重新赋值了, 所以导致默认的constructor被覆盖。
此时的obj.constructor将指向的是Object。 改写一下上面的:
Person.prototype = {
constructor: Person, //强制指向Person
getName: function(){
alert(this.name);
},
getAge: function(){
alert(this.age);
}
}
此时constructor就指向Person了。 prototype是一个函数属性, 此属性同时也是一个对象, 保存着对象实例所共有的属性和方法。 分析这句话:
1.prototype是函数属性, 只要是函数, 就有prototype属性. 而不管是构造函数还是普通函数.
2.prototype同时也是对象.
2.prototype放的是公共的东西, 包括属性和方法. 例子1.
function Person(name, age){
this.name = name;
this.age = age;
} //是函数就有prototype属性, 这个属性也是一个对象
Person.prototype = {
getName: function(){ //所有对象实例都共享
return this.name;
},
getAge: function(){//所有对象实例都共享
return this.age;
}
} var obj = new Person('tom', 23);
obj.getName(); //'tom'
var obj2 = new Person('jack', 23);
obj2.getName(); //'jack'
obj.getName == obj2.getName; //true, 所有实例共享
Person.prototype.getName(); //当做普通函数属性, 根据this定义, 此时this指向的是Person.prototype, 所以返回undefined 以上就是this, constructor, prototype的定义和他们之间的关系. 可能还有些粗糙, 欢迎大家补充. 综合例子: var Tinker = function(){
this.elements = []; };
Tinker.fn = Tinker.prototype = {
constructor: Tinker,
extend: function(obj){
var p;
for(p in obj){
this.constructor.prototype[p] = obj[p];//此处若看明白了, 那么前面的就理解了
}
} }
Tinker.fn.extend({
get: function(){
var length = arguments.length,
i = 0;
for(; i < length; i++){
this.elements.push(document.getElementById(arguments[i])); //此处若看明白了, 那么前面的就理解了
}
return this;//此处若看明白了, 那么前面的就理解了
},
each: function(fn){
var i = 0,
length = this.elements.length;
for(; i < length; i++){
fn.call(this.elements[i], i, this.elements[i]);
}
return this;//此处若看明白了, 那么前面的就理解了
} }); 这个例子其实很简单, 就是向一个对象原型添加方法.一个方法是get, 用于查找页面id. 一个是each, 用于对找到的id元素执行一个方法
//假设有id = 'data', id = 'message'
var obj = new Tinker();
obj.get('data', 'message').each(function(i, item){
this.style.cssText = 'height:20px; background:#ff0000';
})
彻底搞清javascript中this, constructor, prototype的更多相关文章
- 深入浅析JavaScript中的constructor
constructor 属性返回对创建此对象的数组函数的引用.本文给大家介绍JavaScript中的constructor ,需要的朋友参考下吧 定义和用法 constructor 属性返回对创建此对 ...
- JavaScript中的Array.prototype.slice.call()方法学习
JavaScript中的Array.prototype.slice.call(arguments)能将有length属性的对象转换为数组(特别注意: 这个对象一定要有length属性). 但有一个例外 ...
- 【转】JavaScript中的constructor与prototype
最初对js中 object.constructor 的认识: 在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下 ...
- JavaScript中__proto__与prototype的关系
一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...
- JavaScript中的constructor和继承
概述 这是我在看JavaScript面向对象编程指南的时候,对constructor和继承的总结. 关于它们的详细知识,可以上网查到,所以我只写那些网上没有的. 内容 constructor的理解 c ...
- 【你不知道的javaScript 上卷 笔记7】javaScript中对象的[[Prototype]]机制
[[Prototype]]机制 [[Prototype]]是对象内部的隐试属性,指向一个内部的链接,这个链接的作用是:如果在对象上没有找到需要的属性或者方法引用,引擎就 会继续在 [[Prototyp ...
- JavaScript中__proto__与prototype的关系(转)
一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...
- javascript中原型(prototype)与原型链
javascript是一门动态语言(动态语言Dynamic Programming Language:动态类型语言,意思就是类型的检查是在运行时做的,也就是常说的“弱类型”语言),没有类的概念,有cl ...
- [转] 理解 JavaScript 中的 Array.prototype.slice.apply(arguments)
假如你是一个 JavaScript 开发者,你可能见到过 Array.prototype.slice.apply(arguments) 这样的用法,然后你会问,这么写是什么意思呢? 这个语法其实不难理 ...
随机推荐
- uialertview 改变文字显示位置
- (void)willPresentAlertView:(UIAlertView *)alertView{ UIView * view = [alertView.subviews objectAtI ...
- Notepad++中常用的插件
Notepad++中常用的插件 Notepad++实用插件分享 otepad++前端开发常用插件介绍
- 利用 random 与 tertools 模块解决概率问题
Python 中的 random 与 tertools 模块可以得到伪随机数与排列.组合,下面利用这两个模块求解一些有趣的概率问题. 一.random 与 tertools 模块 random 模块常 ...
- 从maya导入物体 Importing Objects From Maya
原地址:http://game.ceeger.com/Manual/HOWTO-ImportObjectMaya.html Unity natively imports Maya files. To ...
- Nginx搭建flv视频点播服务器
Nginx搭建flv视频点播服务器 前一段时间使用Nginx搭建的多媒体服务器只能在缓冲过的时间区域内拖放, 而不能拖放到未缓冲的地方. 这就带来了一个问题: 如果视频限速的速率很小, 那么客户端观看 ...
- Set Matrix Zeroes
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click ...
- HDU4836 The Query on the Tree(树状数组&&LCA)
由于智力的问题,百度之星完全lu不动..开场看第一题根据题目给的条件我觉得一定是可以构造出来的,题目给的意思颇有鸽巢原理的感觉,于是觉得开场第一题应该就是智力构造题了,想了半个小时,发现完全想不动,于 ...
- Activity学习(三)——跳转传值
Activity跳转与传值,主要是通过Intent类来连接多个Activity,以及传递数据. Intent是Android一个很重要的类.Intent直译是“意图”,什么是意图呢?比如你想从这个 ...
- iOS多线程的初步研究(二)-- 锁
谈到线程同步,一般指如何对线程间共享数据的同步读写,如何避免混乱的读写结果.一个基本的解决办法就是使用锁(LOCK). iOS提供多种同步锁的类和方法,这里介绍下基本用法. 1. NSLock:最基本 ...
- CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写
Q: CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写 A: 建议统一写,CI框架会自动识别已经加载过的类,所以不用担心重复加载的问题 class C_User ...