第5章 原型

5.1 原型属性

        function f(a,b){
return a*b;
};
// length 属性
f.length; //
// constructor 构造属性
f.constructor; // function Function() { [native code] }
// prototype 属性 初始值是空对象
typeof f.prototype; //"object"

5.1.1 利用原型添加方法和属性

        function f1(name,color){
// 使用this添加属性
this.name=name;
this.color=color;
this.whatAreYou=function(){
return 'I am a'+this.color+''+this.name;
};
}
// 使用prototype属性添加属性和方法
f1.prototype.price=100;
f1.prototype.rating=3;
f1.prototype.getInfo=function (){
return 'Rating: '+this.rating+',price: '+this.price;
};

5.1.2 使用原型的属性和方法

        function f1(name,color){
// 使用this添加属性
this.name=name;
this.color=color;
this.whatAreYou=function(){
return 'I am a'+this.color+''+this.name;
};
}
// 使用prototype属性添加属性和方法
f1.prototype.price=100;
f1.prototype.rating=3;
f1.prototype.getInfo=function (){
return 'Rating: '+this.rating+',price: '+this.price;
};
var f2=new f1('webcam','black');
f2.color; // "black"
f2.getInfo(); //"Rating: 3,price: 100"
// 修改prototype属性,由同一构造器创建的所有对象的prototype属性也都会同时发生改变(会影响在修改之前已经创建的对象)
f1.prototype.get=function(what){
return this[what];
}
f2.get('price'); //

5.1.4 利用自身属性重写原型属性

对象自身属性的优先级高于原型属性

       function F1(name){
this.name=name;
};
F1.prototype.name='Alen';
var f2=new F1('XiaoMing');
f2.name; // "XiaoMing" 不是 Alen
// 使用hasOwnProperty()判断一个属性是自身属性还是原型属性
f2.hasOwnProperty('name'); //true
//删除自身属性后,原型属性才会显示
delete f2.name; // true
f2.name; // "Alen"

5.1.5 isPrototypeOf()方法

isPrototypeOf():当前对象是否为另一个对象的原型

        var person={
like:'eat',
age:12,
sex:'boy'
};
function F1(name){
this.name=name;
}
F1.prototype=person;
var f2=new F1('Alen');
// 判断person是否为f2的原型
person.isPrototypeOf(f2); //true
//使用getPrototypeOf()获取原型
Object.getPrototypeOf(f2)===person; //true

5.1.6 神秘的__proto__链接

5.2 扩展内建对象

内建对象的构造器函数可以通过其原型来进行扩展。

     <script type="text/javascript">
// 示例1:扩展Array的内建函数,用来查询数组中是否存在某个特定的值
Array.prototype.inArray=function(needle){
for (var i = 0; i < this.length; i++) {
if(this[i]===needle){
return true;
}else{
return false;
}
};
};
var colors=['red','black','blue'];
colors.inArray('red'); //true
colors.inArray('green'); //false
//示例2:反转字符串
// 先利用split()将目标字符串转换成数组,然后调用该数组的reverse()方法产生一个反向数组。
// 最后通过join()方法将结果数组转换为字符串
String.prototype.reverse=function (){
return Array.prototype.reverse.apply(this.split('')).join('');
};
"bums".reverse(); //smub
</script>

5.2.1 关于内建对象的讨论

如果想通过原型为某个对象添加一个新属性,务必检查一下该属性是否已经存在。

5.2.2 原型陷阱

注意: 1> 当对原型对象执行完全替换时,可能会触发原型链中某种异常

2> prototype.constructor 属性不可靠

 <script type="text/javascript">
function Dog(){
this.tail=true;
};
var f1=new Dog();
var f2=new Dog();
// 仍可以为Dog()的原型添加属性,添加之前已经存在的对象也可访问新属性
Dog.prototype.say=function(){
return 'worf';
};
// f1、f2可以访问新方法
f1.say(); //"worf"
f2.say(); //"worf"
// 检查对象的构造器
f1.constructor === Dog; // true 正常
f2.constructor === Dog;// true 正常
Dog.prototype.constructor === Dog; // true // 用自定义新对象完全覆盖掉原有的原型对象
Dog.prototype={
paws:4,
hair:true
};
// 这样原有对象不能访问新属性,但通过__proto__与原有的原型保持联系
f1.paws; //undefined
f1.say(); //"worf"
typeof f1.__proto__.say; // "function"
// 之后创建的对象室友被更新后的prototype对象
var f3=new Dog();
f3.say(); // f3.say is not a function
f3.tail; // true
f3.paws; //
// __proto__指向新的原型对象
f3.__proto__.hair; //true // 新对象的constructor属性不在保持正确
f3.constructor;// function Object() { [native code] }
// 本应该指向Dog(),现在指向Object
f1.constructor; //function Dog(){this.tail=true;} 仍为Dog() 不变
Dog.prototype.constructor; // function Object() { [native code] }
//重新设置constructor属性 解决
Dog.prototype.constructor=Dog;
new Dog().constructor === Dog; // true
</script>

JavaScript面向对象编程指南(五) 原型的更多相关文章

  1. 「JavaScript面向对象编程指南」原型

    在 JS 中,函数本身也是一个包含了方法(如apply和call)和属性(如length和constructor)的对象,而prototype也是函数对象的一个属性 function f(){} f. ...

  2. 《JavaScript面向对象编程指南(第2版)》读书笔记(一)

    目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...

  3. 《JavaScript面向对象编程指南(第2版)》读书笔记(二)

    <JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...

  4. 《JavaScript面向对象编程指南》读书笔记②

    概述 <JavaScript面向对象编程指南>读书笔记① 这里只记录一下我看JavaScript面向对象编程指南记录下的一些东西.那些简单的知识我没有记录,我只记录几个容易遗漏的或者精彩的 ...

  5. 《JavaScript面向对象编程指南》读书笔记①

    概述 JavaScript快忘完了,想看一本专业书拾遗,所以看了这本<JavaScript面向对象编程指南>. 个人觉得这本书讲的很透彻很易懂,一些原来有疑惑的地方在这本书里面豁然开朗,看 ...

  6. 闭包初体验 -《JavaScript面向对象编程指南》

    下面是我对闭包的理解:(把他们整理出来,整理的过程也是在梳理) 参考<JavaScript面向对象编程指南> 1.首先,在理解闭包之前: 我们首先应该清楚下作用域和作用域链 作用域:每个函 ...

  7. 《JavaScript面向对象编程指南》

    第一章.引言 1.5 面向对象的程序设计常用概念 对象(名词):是指"事物"在程序设计语言中的表现形式. 这里的事物可以是任何东西,我们可以看到它们具有某些明确特征,能执行某些动作 ...

  8. 《JavaScript面向对象编程指南》译者序

    相对于Perl.Python等动态脚本语言来说,JavaScript确实是一门饱受误解的语言.对于译者这种从20世纪90年代末走过来的C++程序员来说,尤其如此.在那个年代,提起JavaScript总 ...

  9. JavaScript面向对象编程指南

    引言 面向对象程序设计 基本数据类型.数组.循环及条件表达式 基本数据类型 函数 函数Function 预定义函数 变量的作用域 函数也是数据 闭包 对象 原型 原型 继承 原型链 浅拷贝与深拷贝 原 ...

随机推荐

  1. [node.js] fs.renameSync()报错

    初学node.js,跟着node入门,操作了一遍.在最后一步,上传图片并显示时遇到报错 fs.js: throw err; ^ Error: ENOENT: no such file or direc ...

  2. chrome浏览器被reimage pair 劫持怎么处理

    不知道什么原因chrome浏览器被reimage pair劫持了,只要在浏览器内部一按回车,就马上进入了reimage pair下载的界面. 在网上找了很多解决方法,最后才在google的chrome ...

  3. PHP拿到接口数据返回的json以及传参-----ajax 跨域请求 ---

    以下测试------ <php $ch = curl_init(); $str = '';//此处为接口地址以及传参------- curl_setopt($ch, CURLOPT_URL, $ ...

  4. 橙色优学:Java编程怎么提升技术,Java编程思维至关重要

    橙色优学了解做为程序员,一旦进入技术行列,就开启了持续学习的道路,更迭迅速的互联网时代,技术自然也是一代一代的更新,在技术进阶的道路上,要不断吸收新的想法和技术知识. 牛逼的人总是让人羡慕,但如何才能 ...

  5. centos7系统配置记录SFTP操作日志

    1.修改ssh配置 [root@elk-node2 ~]# vim /etc/ssh/sshd_config 大概132行把下面这个句注释掉 #Subsystem       sftp    /usr ...

  6. HPE服务器做raid5阵列

    HPE服务器做阵列的详细步骤: 注意:HPE服务器加硬盘需要安装配套的扩展笼~~~ 1.首先服务器开机,出现下图界面按F10. 2.然后在下图中选择HPE interlligent Provision ...

  7. rest-framework之APIView 序列化组件

    rest-framework之APIView 一 安装djangorestframework 方式一:pip3 install djangorestframework 方式二:pycharm图形化界面 ...

  8. 自动化运维Ansible安装篇

    Ansible自动化工具之--部署篇 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了 ...

  9. Java多线程之一

    进程与线程 进程 进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位,比如我们windows电脑上运行的一个程序就是一个进程.在传统进程中进程是资源分配和调度的一个基本单位,在后来引入线 ...

  10. Hadoop学习笔记(五):java开发MapReduce

    1. MapReduce的流程图(摘自马士兵老师视频),我们开发的就是其中的这两个(红框)过程.简述一下这个图,input就是我们需要处理的文件(datanode上文件的一个分块):Split就是将这 ...