# 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. 从NSSRound#1学到了什么

    sql_by_sql 二次注入: 更改密码的功能形如: update user set password='%s' where username='%s'; 的语句就可以存在二次注入,即假设有个adm ...

  2. 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  3. awk应用场景之过滤举例

    以/etc/passwd举例,passwd文本 [root@196 tmp]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bi ...

  4. 好客租房13-在jsx中使用javascript表达式

    嵌入js表达式 数据存储在js中 语法{javascript表达式} 注意语法中是单大括号 不是双大括号 //导入react     import React from "react&quo ...

  5. 105_Power Pivot财务科目(层级深度&筛选深度)

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 1.背景 在财务科目中,需要按照科目层级来显示:在excel中都是用公式来实现,而且对于数据的管理及更新是一件头痛的事情, ...

  6. swiper使用

    swiper使用 初始化 var mySwiper = new Swiper ('容器区域类', { // 存放swiper属性 }) 属性 基本属性: 1.initialSlide 设定初始化时sl ...

  7. 基于云服务MRS构建DolphinScheduler2调度系统

    摘要:本文介绍如何搭建DolphinScheduler并运行MRS作业. 本文分享自华为云社区<基于云服务MRS构建DolphinScheduler2调度系统>,作者: 啊喔YeYe . ...

  8. ACM 刷题记录

    HDU Multi-University Training Contest 题目来源 题目 知识点 时间复杂度 完成情况 2019 Contest8 A Acesrc and Cube Hyperne ...

  9. HYPERMESH-NASTRAN梁的方向与偏置

    Nastran关于梁的定义 我们知道,在定义梁单元时,一般需要定义单元的方向,或者说是单元的局部坐标系.对于Nastran内CBAR单元来说,梁轴向为X方向,我们需要给出向量\(\overrighta ...

  10. 数据分析工具Metabase--Metabase安装(最详细的安装教程)

    Meatabase介绍 Metabase 是一款开源的BI工具.主要可以实现在线的可视化分析,单独生成分析图标,定时刷新数据集,权限管理,报告分享等一系列功能. Metabase支持多种市面上主流的数 ...