原型链—— javascript
目录
js面向对象编程
js面向对象编程不同于 java 的类和对象
JavaScript 不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。
js声明的构造函数,类似于普通函数的声明,但又不同,
实例对象时,如果不写new,就是一个普通函数,它返回 undefined。
但是,如果写了new,它就变成了一个构造函数,它绑定的 this 指向新创建的对象,
并默认返回 this,也就是说,不需要在最后写return this;。
js原型链
代码段一:
function Student(name){
this.name = name;
this.say = function(){
console.log('my name:', this.name);
}
}
let student1 = new Student('student1');
let student2 = new Student('student2');

console.log(student1.constructor === Student.prototype.constructor) // true
橙色箭头表示原型链,其原型链为:
student1 --> Student.prototype --> Object.prototype --> null
当我们用 obj.xx 访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,
如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,
最后,如果还没有找到,就只能返回undefined。
共享方法
代码段二:
function Student2(){
this.say = function(){
console.log('hi')
}
}
console.log(new Student2().say === new Student2().say)
结果:
false
实例化的对象方法,虽然方法名称和代码完全一样,但是不同对象指向的不是同一个方法
需要创建一个共享的方法,
根据原型链图,需要将这个共享方法声明在 Student2 的原型对象上,
xxx.prototype.xxx = function(){}
function Student2(){
this.say = function(){
console.log('hi')
}
}
Student2.prototype.publicSay = function(){
console.log('public say');
}
console.log(new Student2().say === new Student2().say)
console.log(new Student2().publicSay === new Student2().publicSay)
结果:
false
true
原型继承
学过 java 的都知道,类的继承通过 extends 会很容易实现,
但是 javascript 的原型继承有点麻烦,不过 class继承就很方便
function Father(name){
this.say = function(){
console.log(name)
}
}
function Son(name){
Father.call(this, name)
}
console.log(Son.prototype.__proto__) // Object
这样看似继承了,但是其原型链的指向并没有改变
其原型链图为:

要实现原型继承,看图的话很容易,只需要将 Son 的原型对象的原型指向 Father 的原型对象

要实现原型继承,这里有三种方法,
法一:
这个方法简介明了,但是不推荐直接通过 __proto__ 直接改变原型
function Father(name){
this.say = function(){
console.log(name)
}
}
function Son(name){
Father.call(this, name)
}
Son.prototype.__proto__ = Father.prototype;
console.log(Son.prototype.__proto__) // Father
法二:
通过实例化 Father 生成一个对象,
new Father() 的原型会默认指向 Father 的原型
通过修改 Son 的 prototype 属性和 new Father() 的 constructor 属性,
来绑定 Son 和 new Father() 之间的关系

function Father(name){
this.say = function(){
console.log(name)
}
}
function Son(name){
Father.call(this, name)
}
Son.prototype = new Father();
Son.prototype.constructor = Son;
console.log(Son.prototype.__proto__) // Father
法三:
类似法二,声明一个中间对象来改变指向

Mid.prototype = Father.prototype;
Son.prototype = new Mid();
Son.prototype.constructor = Son;
第一步,将 Mid 的原型对象指向 Father 的原型对象,
第二步,将 Son 的属性 prototype 指向 Mid,
此时代码上的 new Mid(),实际上是 new Father(),
第三步,将 Son.prototype.constructor 也就是 Mid.prototype.constructor 指向 Son

看起来有点乱,看数字步骤,方便理解
function Father(name){
this.say = function(){
console.log(name)
}
}
function Son(name){
Father.call(this, name)
}
Mid.prototype = Father.prototype;
Son.prototype = new Mid();
Son.prototype.constructor = Son;
console.log(Son.prototype.__proto__) // Father
class继承
ES6 提供了关键字 class,定义类变得更便捷
共享方法
class Father{
// 构造方法
constructor(name){
this.name = name;
}
hello(){
console.log("hello", this.name)
}
}
console.log(new Father("f").hello === new Father("f").hello)
// true,共享方法
class继承
class Father{
// 构造方法
constructor(name){
this.name = name;
}
hello(){
console.log("hello", this.name)
}
}
class Son extends Father{
constructor(name){
super(name);
}
}
console.log(Son.prototype.__proto__) // Father
原型链—— javascript的更多相关文章
- javascript中原型(prototype)与原型链
javascript是一门动态语言(动态语言Dynamic Programming Language:动态类型语言,意思就是类型的检查是在运行时做的,也就是常说的“弱类型”语言),没有类的概念,有cl ...
- 《JavaScript 闯关记》之原型及原型链
原型链是一种机制,指的是 JavaScript 每个对象都有一个内置的 __proto__ 属性指向创建它的构造函数的 prototype(原型)属性.原型链的作用是为了实现对象的继承,要理解原型链, ...
- javaScript系列 [04]-javaScript的原型链
[04]-javaScript的原型链 本文旨在花很少的篇幅讲清楚JavaScript语言中的原型链结构,很多朋友认为JavaScript中的原型链复杂难懂,其实不然,它们就像树上的一串猴子. 1.1 ...
- JavaScript原型与原型链,原型的实际应用
原型链是js面向对象的基础,非常重要. 一,创建对象的几种方法: 1,字面量 var o1 = { name:'o1' }; 2,构造函数 var M = function(name){ this.n ...
- 图解JavaScript中的原型链
转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...
- JavaScript 原型链 OOP(二)
原型对象 `prototype` - 原型对象的所有属性和方法,都能被实例对象共享; JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板.实例对象的属性和方法,可以定义 ...
- 原型链、闭包四种作用、继承、命名空间、枚举类型(day13)
原型链 JavaScript 对象是动态的属性“包”(指其自己的属性).JavaScript 对象有一个指向一个原型对象的链.当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型, ...
- js 原型链(转)
1.1 理解原型链 JavaScript中几乎所有的东西都是对象,我们说数组是对象.DOM节点是对象.函数等也是对象,创建对象的Object也是对象(本身是构造函数),那么有一个重要的问题:对象从哪里 ...
- Inheritance and the prototype chain 继承和 原型 链
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain Inherita ...
随机推荐
- weblogic报:java.lang.LinkageError: loader constraint violation in interface itable initialization
原因分析: gdaml服务中依赖org.apache.xerces_2.9.0.v201101211617.jar会产生jar包冲突 解决方法: 项目中的这个jar包删除,并将这个jar包放在服务器中 ...
- 一、基础篇--1.1Java基础-什么是java的序列化和反序列化
什么是序列化和反序列化 序列化:把堆内存中的java对象数据,通过某种方式把对象存储到磁盘文件或者传递给其他网络节点.这个过程称为序列化.简单来说呢,就是将对象转换成二进流的过程. 反序列化:把磁盘 ...
- CSS - 架构
MaintainableCSS 原子类几乎只有比行内样式少写几个字符这一个优点,缺点倒是一堆,最好别用 一味追求 "永远不要重复同样的事情两次" 会导致过度思考和过度设计,最终出现 ...
- 前端必须掌握的 nginx 技能(4)
概述 作为一个前端,我觉得必须要学会使用 nginx 干下面几件事: 代理静态资源 设置反向代理(添加https) 设置缓存 设置 log 部署 smtp 服务 设置 redis 缓存(选) 下面我按 ...
- spring整合activeMQ遇到异常:Error creating bean with name 'connectionFactory'
异常详情 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connect ...
- select框动态添加选项
$.ajax({ url : "${staticServer }/ywgl/zkpzgl/zkfkgl/showBillType.htm", //ajax请求路径 type : & ...
- 阶段3 2.Spring_06.Spring的新注解_8 spring整合junit完成
Junit的核心Runner在执行的时候不会创建容器.同时它字节码文件,也改不了 spring整合junit 想办法把junit里面的不能加载容器的main方法换掉.从而实现创建容器.有了容器就可以实 ...
- 阶段3 2.Spring_03.Spring的 IOC 和 DI_5 BeanFactory和ApplicationContext的区别
核心容器的两个接口.ApplicationContext和BeanFactory 怎么知道对象被创建了呢 我们只需要在实现类里面构造函数内打印输出一段话 然后再这里加上一个断点 运行程序,光标停在这个 ...
- monkeyrunner初试
Monkeyrunner学习心得 在网上下载并且配置好python,androidsdk和jdk的环境之后,在cmd中运行一下python,java -vesion和monkeyrunner,使之都可 ...
- 在IOS系统中微信浏览器input输入框输入值无效
[contenteditable="true"], input, textarea { -webkit-user-select: auto!important; -khtml-us ...