【JavaScript】第三章 原型与原型链
- 如何准确判断一个变量是数组类型
- 写一个原型链继承的例子
- 描述new一个对象的过程
- zepto(或其他框架)源码中如何使用原型链
构造函数
- 构造函数首字母大写
- 构造函数类似于模板
new一个构造函数,返回一个对象的过程
- new的时候把参数传入也可不传
- new函数执行时,创建一个空对象
- this指向这个新对象
this = {}
- 执行代码,即对this.name等开始顺序赋值
- 赋值完后,默认return this
- 赋值给
f
,f.name
、f.age
、f.class
生效
function Foo(name, age){this.name = name;this.age = age;this.class = 'class-1';// return this //默认有这一行
}
var f = new Foo('zhangsan', 20);
// var f1 = new Foo('lisi', 23); 可创建多个对象
Tips
var obj = {}
其实是var obj = new Object()
的语法糖var arr = []
其实是var arr = new Array()
的语法糖var fn = funtion () {...}
其实是var fn = new Function()
的语法糖- 所有的引用类型(对象、数组、函数)都有构造函数
- 推荐使用前者的写法
原型
5条原型规则和示例
- 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(
null
除外)
var obj ={};
obj.a = 100 ;
var arr = [];
arr.a = 100;
var fn = function () {};
fn.a = 100;
- 所有的引用类型,都有一个
__proto__
属性(隐式原型属性),属性值是一个普通的对象
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
- 所有函数,都有一个
prototype
属性(显式原型属性),属性值是一个普通的对象
- Number、String、Boolean、Object、Array、Function、Date、RegExp、Error(一定要大写)都是函数
console.log(fn.prototype);
- 所有引用类型,
__proto__
属性值指向(完全等===)他的构造函数的prototype
属性值
console.log(obj.__proto__ === Object.prototype)
- 当试图得到一个对象的某个属性时,若果这个对象本身没有这个属性,那么在它的
__proto__
(即它的构造函数的prototype
)中寻找
// 构造函数
function Foo(name, age){this.name = name;
}
Foo.prototype.alertName = function () {alert(this.name);
}
// 创建实例
var f = new Foo('zhangsan');
f.printName = function () {console.log(this.name);
}
// 测试
f.printName();
f.alertName();
- f本身没有
alertName
的属性,所以会去f的隐式原型__proto__
中去寻找,f的隐式原型__proto__
即为其构造函数Foo的显式原型prototype
,Foo的显式原型已被扩展了alertName
的属性,所以可顺利执行 - this永远指向对象本身,在执行
f.alertName()
的时候会执行到第6行alert(this.name)
,但是这里的this还是f本身
原型链
f.toString()
->f.__proto__
->Foo.prototype
-> 无toString
属性 ->Foo.prototype
是一个对象 ->Foo.prototype.__proto__
->Object.prototype
->f.__proto__.__proto__
Object.prototype.__proto__ = null
// 构造函数
function Foo(name, age){this.name = name;
}
Foo.prototype.alertName = function () {alert(this.name);
}
// 创建实例
var f = new Foo('zhangsan');
f.printName = function () {console.log(this.name);
}
// 测试
f.printName();
f.alertName();
f.toString(); // 要去f.__proto__.__proto__中查找
instanceof
- 判断引用类型属于哪个构造函数的方法
f instanceof Foo
判断逻辑:f
的__proto__
一层一层往上,能否对应到Foo.prototype
f instanceof Object
判断逻辑:f
的__proto__
一层一层往上,是否对应到Object.prototype
循环对象自身属性
- 从上述代码中可得f拥有三个属性:name、printName、alertName
- 但我们往往希望拿到对象本身定义的属性,而不要来自其原型的属性
var item;
for(item in f){// 高级浏览器已经在for in中屏蔽了来自原型的属性// 但这里建议大家加上这个判断,保证程序的健壮性以满足浏览器的兼容性if(f.hasOwnProperty(item)){console.log(item)}
}
题目解答
- 如何准确判断一个变量是数组类型
var arr = []
arr instanceof Array //true
typeof arr //object,typeof是无法判断数组的
- 写一个原型链继承的例子
- 面试千万不要这么写
- 面试写更贴近实战的例子
// 动物
function Animal() {this.eat = function () {console.log('animal eat');}
}
// 狗
function Dog() {this.bark = function () {console.log('dog bark');}
}
Dog.prototype = new Animal();
// 哈士奇
var hashiqi = new Dog();
hashiqi.eat();
hashiqi.bark();
// 一个封装DOM查询的例子
function Elem(id) {this.elem = document.getElementById(id);
}Elem.prototype.html = function (val) {var elem = this.elem;if (val) {elem.innerHTML = val;return this; // 链式操作} else {return elem.innerHTML}
}Elem.prototype.on = function (type, fn) {var elem = this.elem;elem.addEventListener(type, fn);return this; // 链式操作
}var div1 = new Elem('div1');
console.log(div1.html());
div1.html('<p>hello world</p>').on('click', function () {alert('clicked');
}).html('<p>javascript</p>')
- 描述new一个对象的过程
- 创建一个空对象
- this指向这个新对象
- 执行代码即对this赋值
- 返回this
- zepto(或其他框架)源码中如何使用原型链
- 阅读源码是最高效提高技能的方式
- 但不能“埋头苦钻”,有技巧在其中,搜索别人的阅读体会
- 慕课网搜索“zepto设计和源码分析”
- 在面试时说出读过源码并分享心得体会十分加分
- jQuery也可
- Vue、React不建议现在读
【JavaScript】第三章 原型与原型链相关推荐
- JavaScript第三章forEach循环第四课
forEach是ES5中操作数组的一种方法,主要功能是遍历数组,例如: var arr = [1,2,3,4]; arr.forEach(alert); 等价于: var arr = [1, 2, 3 ...
- Javascript第三章数组Array常用方法第三课
第一种JavaScript sort() 方法 更多免费教学文章请关注这里 实例 例子 1 在本例中,我们将创建一个数组,并按字母顺序进行排序: <script type="text/ ...
- Javascript第三章创建数组的两种方式第一课
跟java的区别 ,js中数值没有长度限制,大小可以自动调节, 而java 中的数组是线性的,放同样的类型,而且容量是定制,有限制 跟JAVA的区别 直接在控制台输入对象名,直接能把数组中的数全部查出 ...
- Javascript第三章循环最后一种方法for..in与for区别第二课
for in 主要就是遍历对象 如果索引是字符串的形式,不能用for遍历,因为length识别不了他的长度 可以有for-in的方法 主要对象进行遍历 for in 遍历对象属性 获取的是对象的属性名 ...
- JavaScript高级编程设计(第三版)——第三章:基本概念
系列文章目录 第二章:在html中使用javaScript 第三章:基本概念 第四章:变量作用域和内存问题 目录 系列文章目录 前言 一.语法 1.标识符 2.关键字和保留字 二.数据类型 1.nul ...
- 关于javascript的原型和原型链,看我就够了(二)
温故 创建对象的三种方式 通过对象直接量 通过new创建对象 通过Object.create() js中对象分为两种 函数对象 普通对象 仔细观察如下代码 function Foo(name) {th ...
- JavaScript深入之从原型到原型链
JavaScript深入系列的第一篇,从原型与原型链开始讲起,如果你想知道构造函数的实例的原型,原型的原型,原型的原型的原型是什么,就来看看这篇文章吧. 构造函数创建对象 我们先使用构造函数创建一个对 ...
- 【JavaScript 进阶教程】“原型“与“原型链“【上篇】
文章目录: 一:构造函数 1.1 构造函数使用方法 1.2 构造函数new的执行过程 new 执行过程 1.3 实例成员与静态成员 二: 原型对象 prototype 2.1 为什么有原型对象 2.2 ...
- javascript之原型与原型链
前言 了解JavaScript的原型与原型链有助于我们更深层次的理解这门语言,看过很多相关的文章,写的都很好,下面是根据自己的理解,一步步揭开原型与原型链 正文 一.数据类型 在JavaScr ...
- JavaScript对象、原型、原型链知识总结思维导图
这个思维导图是我对Object,原型,原型链等知识的总结,主要参考高程一书第六章,写完才发现这么多,以后可能会进行精简.内容可能会出现差错,欢迎批评指正.下载==>Github ECMAScri ...
最新文章
- DeepLabv3:语义图像分割
- 为什么okhttpclient不能builder
- python中a=a+2与a+=2的区别
- rip协议中周期性广播路由信息的报文_距离矢量路由协议(RIP)
- HDU 1025 Constructing Roads In JGShining's Kingdom(DP+二分)
- activemq安全设置 设置admin的用户名和密码
- HBase shell执行批量脚本
- 联手三年,获取数千名客户,阿里云如何重构 Elastic 开放免费的技术?
- Spring Autowiring @Qualifier example
- android8.0华为荣耀8,一线|华为手机开启重大升级 荣耀成安卓8.0覆盖机型最多品牌...
- Windows XP系列全下载(均为MSDN原版)
- 修改Android序列号(Serial Number)
- UE4中VR项目的打包和发布
- Gabor滤波器进行纹理分割
- Warshall算法
- iis 自动重启的bat
- 中医针灸学综合练习题库【6】
- LC28 Generate Parentheses
- PC到PC之间怎么传送数据包?包括一个路由器,一个交换机,2台PC,由PCA发送经过交换机,路由器到PC2
- 使用Verilog语言实现时间计数器
热门文章
- svn服务端删除版本库_如何彻底删除SVN中的文件和文件夹(附恢复方法)
- Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> [url] in servlet mapping
- OOA、OOD、OOP是什么?
- 离散数学中偏序关系_《离散数学课件》7偏序关系.ppt
- Python locals() 的陷阱
- Mybatis-Plus一个字段匹配两个字段值
- HTTP发送请求和接收响应的整个流程
- 乔布斯的13句经典妙语
- 2.1数字音频基础知识
- Java 接口的应用:PCI