Javascript 构造函数、原型对象、实例之间的关系
# 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 构造函数、原型对象、实例之间的关系的更多相关文章
- js 原型链、构造函数、原型与实例之间的关系
面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法. 一.构造函数.原型与实例之间的关系 每创建一个函数,该函数就会自动带有一个 prototype 属性.该属性是个指针, ...
- 【面向对象】----【prototype&&__proto__&&实例化对象三者之间的关系】(四)-----【巷子】
1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...
- 【面向对象】【prototype&&__proto__&&实例化对象三者之间的关系】
1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...
- 面向对象---prototype、__proto__、实例化对象三者之间的关系
1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...
- 【iOS开发-72】设置状态栏的两种方式、程序生命周期以及更好地理解几大类(对象)之间的关系
(1)设置状态栏的2种方式 --第一种方式就是我们在控制器中设置,系统默认就是交给视图控制器去管理的,这样不同视图控制器能够自己定义不同的状态栏例如以下: -(BOOL)prefersStatusBa ...
- vue入门之创建第一个实例,挂载点、模板和实例之间的关系
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript中原型对象的应用!
JavaScript中原型对象的应用! 扩展内置对象的方法 我以数组对象为例! // 原型对象的应用 扩展内置对象方法! Array.prototype.sum = function() { var ...
- 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)
摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...
- JavaScript的原型对象prototype、原型属性__proto__、原型链和constructor
先画上一个关系图: 1. 什么是prototype.__proto__.constructor? var arr = new Array; 1. __proto__是原型属性,对象特有的属性,是对象指 ...
随机推荐
- 992. Sort Array By Parity II - LeetCode
Question 992. Sort Array By Parity II Solution 题目大意:给一个int数组,一半是奇数一半是偶数,分别对偶数数和奇数数排序并要求这个数本身是偶数要放在偶数 ...
- requests入门
1.通过GET请求获得搜索结果的网页源代码 import requests name=input("请输入想要搜索的明星:") url=f'https://www.sogou.co ...
- Es图形化软件使用之ElasticSearch-head、Kibana,Elasticsearch之-倒排索引操作、映射管理、文档增删改查
今日内容概要 ElasticSearch之-ElasticSearch-head ElasticSearch之-安装Kibana Elasticsearch之-倒排索引 Elasticsearch之- ...
- 简历应该怎么写,HR看一篇简历仅需要5秒吗,简历模板大全
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 最近有很多小伙伴问奇哥,说奇哥 ...
- C#判断数组或集合中是否含有属性值为value的对象
/// <summary> /// 判断list中是否有某个对象的Id_srvplan为value /// </summary> /// <param name=&quo ...
- ansible-playbook批量修改密码
1. 将服务器ip写到ansible hosts文件中 2. 实现免密登录服务器 将ansible服务器公钥拷贝到目标服务器用户目录下的.ssh/authorized_keys 手动连接一次或者自己写 ...
- 使用navicat连接远程linux mysql数据库出现10061
重启mysql服务 两种方式 1.使用 service 启动:service mysql restart 2.使用 mysqld 脚本启动:/etc/inint.d/mysql restart
- -bash: /usr/local/maven/apache-maven-3.8.1/bin/mvn: 权限不够
chmod a+x /usr/local/maven/apache-maven-3.8.1/bin/mvn
- 把excel的数据导入到SQLSERVER里面,excel的字符串时间在导入sql库显示datetime 数据类型的转换产生一个超出范围的值
这是我Excel导入的数据,准备把这个varchar(50)时间导入我的userInfo表中的出生日期字段datatime,如果你的数据正常,是可以导入的, 但是有些日期可能超出datatime的最大 ...
- Sentinel-流量防卫兵
1.背景 1.1 简介 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentinel 具有以下特征 丰富的应用场景:Sentinel 承接了阿里巴 ...