深入JS第一天:原型和它的小伙伴们(一)
我在这里不说定义,找点问题,再解决问题。
一、原型
Q1:这样做输出的结果是什么?
jQuery= String;
jQuery.prototype.say = function () {
alert('呵呵');
};
var jj = new String();
jj.say();//String是否会有这种方法?
A1:运行之后我们发现,在JQuery中的修改导致了String对象原型的变更。所以我们可以得出结论,如果两个对象相等,那么它们会共用原型,一方进行操作,另一方也会因此改变。
Q2:比较一下上下两段代码有什么不同?
jQuery = function () { };
funcProto = function () { };
jQuery.prototype= funcProto;
funcProto.say = function () {
alert('呵呵');
};
var js = new jQuery();
js.say();
//---------------华丽的分割线----------------
funcProto = jQuery.prototype;
funcProto.say = function () {
alert('呵呵');
};
var js = new jQuery();
js.say();
A2:我们在运行之后就会发现,这二者没有什么区别。我们发现,原型不是一个只读的属性,是可读写的。
Q3:下面的代码有区别么?
jQuery = function () { };
funcProto = function () { };
jQuery.prototype.constructor = funcProto;
funcProto.prototype.say = function () {
alert('呵呵');
};
var js = new jQuery();
js.say();//只写constructor后会输出什么?
//------------------------------------------
funcProto = jQuery.prototype.constructor;
funcProto.prototype.say = function () {
alert('呵呵');
};
var js = new jQuery();
js.say();//只读constructor后这又是啥?
A3:这时我们会发现区别:上面会报错,而下面却输出正常了。想必大家对constructor这个属性的含义并不陌生,通过这个实验我们可以认识到,原型的属性是可读写的,可是在只读和只写时出现了差别。所以我们要注意:在面向对象书写JavaScript的时候,有必要再写完后,重新再确认一次原型中的constructor的指向,否则有时会出现指向错误。为什么上半部分就会失败呢?接着往下看。
Q4:上个问题我们讨论了更改属性不能改变对象性质,那么我们试着去改变对象实例的Constructor的原型呢?
var jj = new String();
jj.constructor.prototype = Array.prototype;
alert(jj.constructor);
String.prototype = Array.prototype;
var jj = new String();
alert(jj.constructor);
A4:我们发现输出false,一个string类型的实例在改写了它的constructor的原型后并没有变成Array类型。而直接更改原型也不行,我们可以得知JavaScript规定,基本类型(Array String Number Function Object RegExp Date等JavaScript引擎中封装好的‘类’)的构造器的原型是只读的,不能赋值。
Q5:看看__proto__指针都指向什么?
alert(String.constructor.prototype === Array.constructor.prototype);//true
alert(String.__proto__ === Array.__proto__);//true
var str = '';
var arr = [];
alert(str.__proto__);
alert(arr.__proto__);
str.__proto__ = arr.__proto__;
alert(str.__proto__ === arr.__proto__);//false
A5:通过实验我们知道,__proto__指针其实就是constructor.prototype,下面的str.__proto__ = arr.__proto__操作是不是和Q4中的String.prototype=Array.prototype一样?所以我们得出结论,constructor.prototype属性是只读的。
现在我们应该能够知道Q3的问题所在,当我们在设置obj2.prototype.constructor=obj的时候却是可读写的,但是更改obj的prototype并不能回推到obj2,我们如果给obj和obj2判等,发现其实二者并不一样。因为obj2的实例的__proto__指针早已设定好指向obj2.prototype,所以Q3上半部分不能成功。而Q3下半部分之所以成功,是因为obj=obj2.prototype.constructor时,obj和obj2指针已经相等,所以改obj和改obj2是等效的。
深入JS第一天:原型和它的小伙伴们(一)的更多相关文章
- 基于原生JS封装数组原型上的sort方法
基于原生JS封装数组原型上的sort方法 最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能.虽然没有深入底层,了解源码.以下解法都是基于 ...
- JS对象与原型
一. JS的对象 1.1 创建对象的几种方式 1.1.1 通过字面量创建对象 在js中,一对{} 其实就是一个对象 var person = { name: "tom", age: ...
- js中的原型、继承的一些想法
最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享 ...
- 01-THREE.JS 第一个场景
THREE.JS第一个场景 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- 谈谈JS中的原型
不知道大家对JS中的原型理解的怎么样,我想如果大家对JS中的原型对象以及prototype属性十分熟悉的话对后面原型链以及继承的理解会十分的容易,这里想和大家分享自己对其的理解,请先看下面这段代码O( ...
- js中原型和原型链
1.原型: 在JavaScript 中,对象被表现为prototype . 原型其实一直存在于我们接触过的任何一个对象. 2. Tip:在函数对象中也存在__proto__属性,但是查看函数对象的原型 ...
- js 构造函数 & 静态方法 & 原型 & 实例方法
js 构造函数 & 静态方法 & 原型 & 实例方法 ES5 "use strict"; /** * * @author xgqfrms * @licens ...
- JS进阶之原型
之前有在自己的文章中谈到对象,而说到对象我们就不可避免的要扯到原型,并且原型也是我们必须得理解到位的一个点,那接下来我们就来聊一聊js的原型吧. JS中一切皆为对象,那么原型也是一种对象.所以它有对象 ...
- JS中的原型继承机制
转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很 ...
随机推荐
- 11.python中的元组
在学习什么是元组之前,我们先来看看如何创建一个元组对象: a = ('abc',123) b = tuple(('def',456)) print a print b
- python 函数的参数对应
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经接触过函数(function)的参数(arguments)传递.当时我们根 ...
- openerp 经典收藏 记录规则 – 销售只能看到自己的客户,经理可以看到全部(转载)
记录规则 – 销售只能看到自己的客户,经理可以看到全部 原文地址:http://cn.openerp.cn/record_rule/ OpenERP中的权限管理有四个层次: 菜单级别: 即,不属于指定 ...
- 远程连接数据库(通过pgAdmin)
1.编辑/var/lib/pgsql/data/pg_hba.conf,增加语句 host all all 192.168.105.225/36 trust 让数据库接受网络 192.168.105 ...
- rails bug
variable @fontAwesomeEotPath_iefix is undefined rails generate bootstrap:install如果还有错,保证在加载主提之前impor ...
- spring debug
DispatcherServlet{ getHandler()}handlerMappings{ RequestMappingHandlerMapping BeanNameUrlHandlerMapp ...
- oracle 修改表空间存储路径
[root@yoon ~]# more /etc/oracle-releaseOracle Linux Server release 5.7 Oracle Database 11g Enterpris ...
- Redo日志
undo日志有一个潜在的问题,即我们在将书屋改变的所有数据写到磁盘前不能提交该事务.有时,如果让数据库修改暂时只存在于主存中,我们可以节省磁盘IO;只要在崩溃发生时有日志可以恢复,这样做就是安全的. ...
- android开发系列之6*0.9不等于5.4
昨天晚上我们客户端平台上面曝出了一个很奇诡的bug,那就是本来在客户端里面有个商品买6元,但是因为碰巧赶上打9折,这个时候我们很自然的处理就是6*0.9.好吧你以为so easy的事情,其实就出错了, ...
- 关于Swift中实现Lazy initialize的方式
在oc中我们通过 -(CardMatchingGame *)game { if(!_game) _game=[[CardMatchingGame alloc] initWithCardCount:[s ...