# Javascript 构造函数、原型对象、实例之间的关系

# 创建对象的方式
# 1.new object() 缺点:创建多个对象困难
var hero = new Object(); // 空对象
hero.blood = 100;
hero.name = '刘备';
hero.weapon = '剑';
hero.attack = function () {
console.log(this.weapon + ' 攻击敌人');
} # 2.对象字面量 缺点:创建多个对象困难
var hero = {
blood: 100,
name: '刘备',
weapon: '剑',
attack: function () {
console.log(this.weapon + ' 攻击敌人');
}
} # 3.工厂函数 创建多个对象 缺点:无法获取具体类型(typeof 返回结果是Object)
function createHero(name, blood, weapon) {
var o = new Object();
o.name = name;
o.blood = blood;
o.weapon = weapon;
o.attack = function () {
console.log(this.weapon + ' 攻击敌人');
}
}
hero = createHero('刘备', 100, '剑') # 4.通过构造函数来实现 解决了工厂对象遗留的问题
function Hero(name, blood, weapon) {
this.name = name;
this.blood = blood;
this.weapon = weapon;
this.attack = function () {
console.log(this.weapon + ' 攻击敌人');
}
}
var hero1 = new Hero('刘备', 100, '剑');
var hero2 = new Hero('关羽', 100, '刀');
console.log(hero1.constructor === Hero); # 而constructor可以改变,所以不建议这么用
console.log(hero1 instanceof Hero); # 这样看它是否是Hero的对象
console.log(hero1.attack === hero2.attack); # ===比较地址。这里返回False
# 问题一:new Hero具体干了啥?
# .首先会在内存中创建一个空对象
# ..设置构造函数的this,让this指向刚刚创建好的对象
# ...执行构造函数中的代码
# ....返回对象
# 问题二:为什么attack函数不是同一个,却又能通过this去访问实例属性?
# new的时候会执行构造函数中的代码,也就是会执行function ()的时候会创建自己的一个空this对象,所以Hero不同实例的attack其实不是同一个。
# 而调用的时候是通过hero1.attack()和hero2.attack()调用的,这时候this代表的是hero1\hero2,所以能通过this.weapon来调用。
# 问题三:如果需要通过Hero构造函数构造几十上百个对象,那么attack方法不是会浪费很大的资源?
# 解决方案一:将attack声明为全局的,在Hero构造的时候赋值给this.attack。这样的弊端是,当构造方法一多的时候,方法名容易重名。
# 解决方案二:通过构造函数的原型对象去实现。 # 每一个构造函数都有一个属性prototype,也就是原型对象。通过同一个构造函数new出来的实例共享一个原型对象中的属性。
function Student(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Student.prototype.sayHi = function () {
console.log('大家好,我是' + this.name)
}
var s1 = new Student('lilei', 18, '男');
var s1 = new Student('hmm', 18, '女');
s1.sayHi();s2.sayHi();
# 如果原型对象和构造函数中都有sayHi方法的话,优先调用构造函数中的sayHi方法。 # Student构造函数、Student原型对象、Student实例/对象之间的关系
# 1.每个构造函数中都有一个prorotype原型对象
# 2.prorotype原型对象中有一个constructor属性,它指向的是它本身所属的构造函数
# 3.每个实例都有一个__proto__属性,它指向的是构造函数的prototype原型对象
# 4.因为每个实例都有一个__proto__属性,所以Student构造函数的构的原对象也有__proto__,它就是Object的原型对象
# 5.Object的原型对象的__proto__属性是空
# 得出结论:
# .当获取实例的属性的时候,先从自身直接属性中获取值,如果没有就去__proto__原型对象中获取,原型对象中也没有的话就到Object原型对象中去找,再没有就报错,因为原型对象的__proto__是null。
# ..注意:在实例中设置属性的时候不会影响原型对象。因为设置的时候实例本身不具备属性是直接新增属性,并不会修改原型中的属性。
# ...你可以直接通过实例.constructor属性可以判断实例是属于哪个构造函数的。
# 如果需要在原型对象中设定多个函数的话,你可以这么做
function Student(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Student.prototype = {
constructor: Student, # 这里必须设定,不然就没办法找到所属构造函数
sayHi: function () {
console.log('大家好,我是' + this.name)
}
}

Javascript 构造函数、原型对象、实例之间的关系的更多相关文章

  1. js 原型链、构造函数、原型与实例之间的关系

    面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法. 一.构造函数.原型与实例之间的关系 每创建一个函数,该函数就会自动带有一个 prototype 属性.该属性是个指针, ...

  2. 【面向对象】----【prototype&&__proto__&&实例化对象三者之间的关系】(四)-----【巷子】

    1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...

  3. 【面向对象】【prototype&&__proto__&&实例化对象三者之间的关系】

    1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...

  4. 面向对象---prototype、__proto__、实例化对象三者之间的关系

    1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...

  5. 【iOS开发-72】设置状态栏的两种方式、程序生命周期以及更好地理解几大类(对象)之间的关系

    (1)设置状态栏的2种方式 --第一种方式就是我们在控制器中设置,系统默认就是交给视图控制器去管理的,这样不同视图控制器能够自己定义不同的状态栏例如以下: -(BOOL)prefersStatusBa ...

  6. vue入门之创建第一个实例,挂载点、模板和实例之间的关系

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. JavaScript中原型对象的应用!

    JavaScript中原型对象的应用! 扩展内置对象的方法 我以数组对象为例! // 原型对象的应用 扩展内置对象方法! Array.prototype.sum = function() { var ...

  8. 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)

    摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...

  9. JavaScript的原型对象prototype、原型属性__proto__、原型链和constructor

    先画上一个关系图: 1. 什么是prototype.__proto__.constructor? var arr = new Array; 1. __proto__是原型属性,对象特有的属性,是对象指 ...

随机推荐

  1. 【Java8新特性】Lambda表达式

    一.Lambda 表达式 是什么? Lambda读音:拉姆达. Lambda是一个匿名函数,匿名函数就是一个没有名字的函数. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). ...

  2. 好客租房28-state和this.setState(this.setState修改状态)

    状态是改变的 语法:this.setstate 千万不要直接改变this.setState setState 修改state 更新ui 数据驱动视图 //导入react     import Reac ...

  3. DeepPrivacy: A Generative Adversarial Network for Face Anonymization阅读笔记

    DeepPrivacy: A Generative Adversarial Network for Face Anonymization ISVC 2019 https://arxiv.org/pdf ...

  4. Ajax——Get请求

    Get.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. Unity-自定义事件派发器的两次尝试

    一.前言: 在游戏开发的很多时候,需要引用其他类的方法,但是一旦类多起来了,相互引用会导致引用关系混乱,极其难以阅读. 以前初次做抖音小游戏时,和一位经验老道的cocos程序员合作,看到我写的代码他不 ...

  6. dubbo的消费者是怎么获取提供者服务接口引用的?

    本文主要解读dubbo消费者是如何引用服务端接口的,是如何像本地调用一样调用远程服务的. 并试着从设计者的角度思考,为何这样设计. @Component public class DubboConsu ...

  7. kubernetes code-generator使用

    目录 Overview Prerequisites CRD code-generator 编写代码模板 code-generator Tag说明 开始填写文件内容 type.go doc.go reg ...

  8. Linux 源码编译安装软件

    程序包编译安装的步骤: 源代码-->预处理-->编译-->汇编-->链接-->执行 多文件:文件中的代码之间,很可能存在跨文件依赖关系 1.编译源码的项目工具 使用相关的 ...

  9. NC24325 [USACO 2012 Mar S]Flowerpot

    NC24325 [USACO 2012 Mar S]Flowerpot 题目 题目描述 Farmer John has been having trouble making his plants gr ...

  10. go grpc: connection reset by peer 的一种解决方案

    最近添哥一直反映,他手下的设备以grpc stream的方式向我服务端发送数据.偶然会收到错误.现象如下: 连接已经建立了一段时间,正常使用. 突然client.Send 返回 eof. 客户端有报错 ...