JavaScript学习(二)——深入学习js对象的原型与继承
了解对象
对象的声明的两种方式
var person = new Object();
person.name="linchen";
person.age="18";
person.job="java"; var person={
name:"linchen",
age:"18",
job:"java"
}
对象的数据属性和访问器属性
懒得写了,这骚操作没啥用,给出相关链接:
https://blog.csdn.net/qq_17371033/article/details/52688195
创建对象
构造函数
构造函数也是函数,是比较特殊的函数。
这种函数是用来创建对象的,就好比普通函数最后return一个对象一样。
区别在于构造函数没有显式的创建对象,直接将属性和方法赋给了this,没有return语句。
例:
//构造函数:
// 物质(属性:质量,速度,是否生物)
function Material(quality,speed,isLivingText) {
this.quality = (quality||0) + "kg";
this.speed = (speed||0) + "m/s";
this.isLiving = isLivingText == "生物";
this.setSpeed = function(num) {
this.speed = num + "m/s";
}
}
// 创建一个对象,需要用new关键字
var body1=new Material(50,5,"生物");
var body2=new Material(100,0,"非生物");
//用普通函数创建对象:
function material(quality,speed,isLivingText) {
var obj={};
obj.quality = (quality||0) + "kg";
obj.speed = (speed||0) + "m/s";
obj.isLiving = isLivingText == "生物";
obj.setSpeed = function(num) {
obj.speed = num + "m/s";
}
return obj;
}
var body3=material();
var body4=material(100,0,"非生物");
这种用函数来封装以特定接口创建对象的细节的模式被称为工厂模式
通过new关键字来创建对象的模式被称为构造函数模式
原型对象
1、任何函数都有一个属性:prototype (原型)
prototype指向一个原型对象
该原型对象包含由该构造函数创建的所有实例共享的属性和方法。
2、任何对象都有一个隐藏的属性: __proto__
__proto__属性的值指向该构造函数的原型对象。
3、任何原型对象都有一个属性:constructor (构造函数)
constructor指向该原型对象对应的构造函数。
4、原型对象也是对象,也会有一个__proto__属性
假如原型对象是另一个构造函数的实例,则形成原型链。
原型链的终点必是构造函数Object()的原型
其原型的__proto__属性值为null
5、原型对象的设置方法:
// 修改单个属性或方法
Material.prototype.quality="0kg";
Material.prototype.setQuality = function(num) {
this.quality = num + "kg";
}; // 初始化原型对象
Material.prototype={
quality:"0kg",
setQuality:function(num) {
this.quality = num + "kg";
};
} // 原型对象是另一个对象的实例
Material.prototype=new Object();
6、原型对象是动态的,当我们对原型对象所做了任何修改都会在所有实例上反映出来。
例:
var body1=new Material();
body1.setSpeed(20); //body1.setSpeed is not a function
console.log(body1.speed);
Material.prototype.setSpeed=function(num){
this.speed=num+"m/s";
}
body1.setSpeed(40);
console.log(body1); // 40m/s
继承
什么是继承
一个对象获得另一个对象的所有属性和方法,这个操作叫做继承。
原型式继承
当构造函数a的原型等于构造函数b的实例时,形成一个原型链,通过这样的方式,a就拥有了b所有的属性和方法,这种方式叫做构造函数继承。
缺点:
a创建出来的实例的继承于b的属性和方法都是共享的,改了其中一个实例的属性值,别的实例对应的属性值也会改变。
寄生式继承
通过在构造函数a中调用构造函数b来使a拥有了b所有的属性和方法。这种方式叫做寄生式继承。
使用apply()和call():
function B(name){
this.name=name;
}
function A(name,age){
B.call(this,name);
// B.apply(this,[name])
this.age=age;
}
apply()与call()详解:
https://blog.csdn.net/ganyingxie123456/article/details/70855586 (别人写的)
缺点:
a创建出来的实例不继承b的原型的属性和方法。如果把b的原型的属性和方法都写在b里面也就失去了函数复用的能力了。
组合继承(寄生组合式继承)
先使用寄生式继承来继承,再使用原型式继承。解决了以上两种方式各自的缺点。实例上的属性和方法会屏蔽原型上相同名的属性和方法。
demo
把下面代码复制到一个新建的.html文件,记得引入jquery,打开控制台看console
<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
<script src="jquery1.42.min.js"></script>
</head> <body>
<div id="box1"></div>
<!-- 构造函数,实例 -->
<script id="js1">
// 构造函数,实例--------------------------------------------------
/**
按照惯例:
1、构造函数始终都应该以一个大写字母开头
2、非构造函数则应该以一个小写字母开头 与普通函数的区别:
1、没有显式地创建对象
2、直接将属性和方法赋给了this对象
3、没有return语句
*/ // 物质(属性:质量,速度,是否生物)
function Material(quality,speed,isLivingText) {
this.quality = (quality||0) + "kg";
this.speed = (speed||0) + "m/s";
this.isLiving = isLivingText == "生物";
this.setSpeed = function(num) {
this.speed = num + "m/s";
}
} // 这种用函数来封装以特定接口创建对象的细节的模式被称为工厂模式
// function material(quality,speed,isLivingText) {
// var obj={};
// obj.quality = (quality||0) + "kg";
// obj.speed = (speed||0) + "m/s";
// obj.isLiving = isLivingText == "生物";
// obj.setSpeed = function(num) {
// obj.speed = num + "m/s";
// }
// return obj;
// } // 创建实例,得到一个新对象
var body1 = new Material(50,0,"生物");
console.log(body1); // 继承----------------------------------------------------------
/**
* 继承的方式:
* 1、原型链(主要)(原型式继承)
* 2、借用构造函数(寄生式继承)
* 3、1和2组合继承 (寄生组合式继承)
*/ // 设置质量的方法(原型)
Material.prototype.setQuality = function(num) {
this.quality = num + "kg";
};
// 通过对象
Material.prototype.setOption = function(opt) {
opt = opt || {};
this.quality = (opt.quality || 0) + "kg";
this.speed = (opt.speed || 0) + "m/s";
this.isLiving = opt.isLivingText == "生物";
};
// 速度参照物(原型)
Material.prototype.reference = "地球表面";
body1.setQuality(25);
console.log(body1); // 非生物(构造函数)
function NonLivingThings() { }
// 原型式继承
NonLivingThings.prototype = new Material(null,null,"非生物");
NonLivingThings.prototype.constructor = NonLivingThings;
var nonLifeBody1 = new NonLivingThings();
console.log(nonLifeBody1); // 生物(构造函数)
function LivingThings() {
// 寄生式继承
Material.call(this,null,null,"生物"); //(call写法)
// Material.apply(this, ["生物"]);(apply写法)
this.lifeSpan = 0 + "年";
}
// 原型式继承 -- 因为前面已经实现了寄生式继承,所以实现了寄生组合式继承
// LivingThings.prototype = new Material("生物");
// LivingThings.prototype.constructor = LivingThings;
// 重写原型的setOption函数
// LivingThings.prototype.setOption = function() {
// return function(opt) {
// LivingThings.prototype.setOption.call(this, opt);
// this.lifeSpan = (opt.lifeSpan || 0) + "年";
// }
// }
var lifeBody1 = new LivingThings();
// lifeBody1.setOption({
// "quality": 20,
// "lifeSpan": 100
// });
console.log(lifeBody1);
</script>
<script id="js2">
// 创建一个对象,名为石头
var 石头 = new NonLivingThings("非生物");
石头.setOption({
"speed": 100
});
// 给物质添加一个run函数,传入节点,实现该节点块从左往右滑动
Material.prototype.run = function(dom) {
var $dom=$(dom);
$dom.css({
width: "100px",
height: "100px",
background: "red"
});
$dom.animate({
marginLeft: '+500px'
}, (500 / parseInt(this.speed || 100)) * 1000); };
石头.run("#box1");
</script>
</body> </html>
JavaScript学习(二)——深入学习js对象的原型与继承的更多相关文章
- JS对象与原型
一. JS的对象 1.1 创建对象的几种方式 1.1.1 通过字面量创建对象 在js中,一对{} 其实就是一个对象 var person = { name: "tom", age: ...
- js中的原型、继承的一些想法
最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享 ...
- 最具有性价比的语言javascript之二,学习篇
先祝福各位,国庆假期愉快!前面写了一篇 最具有性价比的语言javascript之介绍篇,引起了不少的争议. 有些人javascript吐槽,埋怨.我目前做的都是后台系统.每个人的工作经历和兴趣爱好不一 ...
- [Effective JavaScript 笔记]第4章:对象和原型--个人总结
前言 对象是js中的基本数据结构.对象在js语言编码中也随处可见,比如经常会用到的函数,也是一个Function构造函数,Function.prototype原型对象.每当声明一个函数时,都会继承Fu ...
- js对象,原型,call,apply浅析
//对象直接量,创建对象最简单的方式是在js里使用对象直接量 var book = { "main title": "js", //属性里有空格,要用引号 &q ...
- JS对象与原型链
每个函数都存在一个prototype的属性,然后这个属性值为一个对象,我们称之为原型对象 每个对象都存在着一个隐藏的属性"__proto__" 这个属性引用了创建这个对象的函数的p ...
- JavaScript的类、对象、原型、继承、引用
以CSS为例,有一种为所有class为"xxxx"的元素添加样式(外联样式),那么所有class为xxx的元素样式就会改变,在css中像下面这么写: <html> &l ...
- 深入理解JS对象和原型链
函数在整个js中是最复杂也是最重要的知识 一个函数中存在多面性: 1.它本身就是一个普通的函数,执行的时候形成的私有作用域(闭包),形参赋值,预解释,代码执行,执行完 成后栈内存销毁/不销毁. 2.& ...
- 从零开始的全栈工程师——JS面向对象( 原型 this 继承)
一.生成对象的方式 ①单例模式(字面量定义)var obj = {} ②类的实例 var obj = new Object( ) ③工厂模式 ④构造函数:扮演三种角色 普通函数 普通对象 类 工厂模式 ...
随机推荐
- 机器学习 MLIA学习笔记(一)
监督学习(supervised learning):叫监督学习的原因是因为我们告诉了算法,我们想要预测什么.所谓监督,其实就是我们的意愿是否能直接作用于预测结果.典型代表:分类(classificat ...
- Paket介绍
在国外.NET社区有一个很火的话题是Packet(https://fsprojects.github.io/Paket/index.html ),它本质上是Nuget 之外的另一种方式管理.NET项目 ...
- Anagram 由颠倒字母顺序而构成的字
2018-07-15 19:23:08 Valid Anagram 问题描述: 问题描述: 可以使用map来记录各个字符出现的个数,在O(n)的时间复杂度内完成,当然也可以使用排序算法在O(nlogn ...
- win10 自己DIY的arp绑定小脚本
@echo off&mode con cols=80 lines=22&title ARP_bind Tools setlocal enabledelayedexpansion rem ...
- EF学习-获取实体框架01
实体框架由 EF 设计器(包含在 Visual Studio 中)和 EF Runtime(在 NuGet 上提供)组成. EF 设计器包含在 Visual Studio 中 最新版本的实体框架设计器 ...
- Ubuntu解压缩zip,tar,tar.gz,tar.bz2文件命令
tar解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName .gz解压1:gunzip FileName.gz解压2:gzip -d FileN ...
- vue新手入门指导,一篇让你学会vue技术栈,本人初学时候的文档
今天整理文档突然发现了一份md文档,打开一看 瞬间想起当年学习vue的艰难路,没人指导全靠自己蒙,下面就是md文档内容,需要的小伙伴可以打开个在线的md编译器看一看,我相信不管是新人还是老人 入门总 ...
- React-Router v4.0 hashRouter使用js跳转
React-Router v4.0上已经不推荐使用hashRouter,主推browserRouter,但是因为使用browserRouter需要服务端配合可能造成不便,有时还是需要用到hashRou ...
- kill prefix extra,endo out 1
1●extra 超过外面的, 以外的,外面 的 2●endo 内部
- 快速切题 sgu116. Index of super-prime bfs+树思想
116. Index of super-prime time limit per test: 0.25 sec. memory limit per test: 4096 KB Let P1, P2, ...