目录

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的更多相关文章

  1. javascript中原型(prototype)与原型链

    javascript是一门动态语言(动态语言Dynamic Programming Language:动态类型语言,意思就是类型的检查是在运行时做的,也就是常说的“弱类型”语言),没有类的概念,有cl ...

  2. 《JavaScript 闯关记》之原型及原型链

    原型链是一种机制,指的是 JavaScript 每个对象都有一个内置的 __proto__ 属性指向创建它的构造函数的 prototype(原型)属性.原型链的作用是为了实现对象的继承,要理解原型链, ...

  3. javaScript系列 [04]-javaScript的原型链

    [04]-javaScript的原型链 本文旨在花很少的篇幅讲清楚JavaScript语言中的原型链结构,很多朋友认为JavaScript中的原型链复杂难懂,其实不然,它们就像树上的一串猴子. 1.1 ...

  4. JavaScript原型与原型链,原型的实际应用

    原型链是js面向对象的基础,非常重要. 一,创建对象的几种方法: 1,字面量 var o1 = { name:'o1' }; 2,构造函数 var M = function(name){ this.n ...

  5. 图解JavaScript中的原型链

    转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...

  6. JavaScript 原型链 OOP(二)

    原型对象 `prototype` -  原型对象的所有属性和方法,都能被实例对象共享;   JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板.实例对象的属性和方法,可以定义 ...

  7. 原型链、闭包四种作用、继承、命名空间、枚举类型(day13)

    原型链 JavaScript 对象是动态的属性“包”(指其自己的属性).JavaScript 对象有一个指向一个原型对象的链.当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型, ...

  8. js 原型链(转)

    1.1 理解原型链 JavaScript中几乎所有的东西都是对象,我们说数组是对象.DOM节点是对象.函数等也是对象,创建对象的Object也是对象(本身是构造函数),那么有一个重要的问题:对象从哪里 ...

  9. Inheritance and the prototype chain 继承和 原型 链

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain Inherita ...

随机推荐

  1. 装win7英文版装系统学习

    1:语言变换,下载Vistalizator ,详细的方法点击:方法见.需要安装语言包,语言包地址请点击:语言包.

  2. 2019java第十二周课程总结

    本周主要还是学习图形界面 各种容器使用方法 如下代码: package text10; import java.awt.*; import java.io.File; import javax.swi ...

  3. Python--安装第三方库的方法

    一:安装方法(以numpy为例,安装其他包把numpy改为包名即可) 1.有设置python包中pip.exe环境变量的情况下 同时按住win+R输入cmd打开cmd,直接输入pip install ...

  4. windows环境安装nexus

    1.下载安装nexus安装包,我用的是nexus-2.14.13-01版本 2. 以管理员身份打开cmd命令窗口 3.进入到nexus bin目录下 输入命令 nexus install 4. 启动 ...

  5. golang 使用reflect反射结构体

    "反射结构体"是指在程序执行时,遍历结构体中的字段以及方法. 1.反射结构体 下面使用一个简单的例子说明如何反射结构体. 定义一个结构体,包括3个字段,以及一个方法. 通过refl ...

  6. 在jsp中出现:Syntax error, insert "Finally" to complete TryStatement错误

    在jsp中出现:Syntax error, insert "Finally" to complete TryStatement错误 可能括号不匹配{}

  7. 在 Android 中进程的级别有哪些?

    a) Foreground processb) Visible processc) Service processd) Background processe) Empty process

  8. 阶段3 2.Spring_07.银行转账案例_6 测试转账并分析案例中的问题

    转账回滚这里把异常打印出来.AccountServiceTest.java 把数据库的金额现在都改成1000块 运行测试方法 这里已经报错了. 刷新数据库内的数据.这样我们事物就控制成功了. 事物控制 ...

  9. 阶段3 2.Spring_04.Spring的常用注解_5 自动按照类型注入

    运行出现了空指针异常 @Autowired 注解出现的位置 AutoWired的代码 常用的就是写类上和方法上. 运行测试,刚才运行是一个空指针异常 也就是通过Autowired 这个accountD ...

  10. 对redis的一些理解

    缓存就是在内存中存储的数据备份,当数据没有发生本质变化的时候,我们避免数据的查询操作直接连接数据库,而是去    内容中读取数据,这样就大大降低了数据库的读写次数,而且从内存中读数据的速度要比从数据库 ...