JS红宝书复习章八对象,类和面向对象编程
Object.assign()
该函数接收两至多个参数:第一个参数为目标对象,之后的参数作为源对象,将源对象中可枚举和自有属性复制到目标对象;
- 对每个源对象执行的是浅复制
const increment = {
count:{
value: 1
},
sum(){
this.count.value
}
}
let obj2 = {
count:3
}
obj2 = Object.assign(obj2,increment)
increment.sum()
obj2.sum()
console.log('1:',increment.count)//1:3
console.log('2:',obj2.count)//2:3
//increment与obj2两个对象中的count执行的是浅复制:只复制对象的引用
对象解构
- 由于对象的属性间没有先后顺序,因此必须注明解构模式:
- 解构模式在左,表示匹配哪个,变量命名在右;想要解构的变量的结构与对象中是一致的;
const target = {
value: 1,
fruit: {
apple: 0,
banana: 1,
orange: 2
},
vegetable: {
tomato: {
like:'yes',
number: 1
},
potato: {
like:'no',
number:0
}
}
}
//解构target,获得value
const { value:value_new } = target
console.log(value_new)//1
//获得fruit与apple
const {fruit:fruit_new,fruit:{ apple:apple_new }} = target
console.log(fruit_new)//对象
console.log(apple_new)//0
//获得vegetable与potato与likes
const {
vegetable:vegetable_new,
vegetable:{
potato:potato_new
},
vegetable:{
potato:{
like:like_new
}
}
} = target
console.log(vegetable_new)
console.log(potato_new)
console.log(like_new)
- 如果一个解构表达式涉及多个赋值,开始的解构赋值成功,后面出错,则整个解构只会完成一部分;匹配不到的值为undefined
- 在函数参数列表中也可以进行解构赋值,对参数的解构赋值不会影响arguments对象,但可以在函数签名中声明在函数体内使用局部变量
8.2 创建对象
8.2.3构造函数模式
构造函数名称的首字母都是要大写的,非构造函数则以小写字母开头。
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name)
}
}
8.2.4原型模式
- 每个函数都会创建一个prototype属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。实际上,这个对象就是通过调用构造函数创建的对象的原型。
- 使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。
1.理解原型
无论何时,只要创建一个函数,就会按照特定的规则为这个函数创建一个prototype属性(即原型对象)。默认情况下,所有原型对象自动获得一个名为constructor的属性,指回与之关联的构造函数。
每次调用构造函数创建一个新实例,**这个实例的内部[[Prototype]]指针就会被赋值为构造函数的原型对象**。一些浏览器(Firefox,Safari,Chrome)会在每个对象上暴露__proto__属性,通过这个属性可以访问对象的原型。
构造函数的原型也是一个对象,因此其内部也有[[Prototype]]属性
2.练习题
//练习1
var F = function() {};
Object.prototype.a = function() {
console.log('a');
};
Function.prototype.b = function() {
console.log('b');
}
var f = new F();
f.a();//a
//f没有a属性,因此查找f的__proto__属性(F.prototype)上也没有a,
//因此查找F.prototype.__proto__上(Object.prototype)
f.b();//报错
//f没有b属性,因此查找f的__proto__属性(F.prototype)上也没有b,
//因此查找F.prototype.__proto__上(Object.prototype)上也没有b
//Object.prototype.__proto__为null:undefined
F.a();//a
//F中没有
//F.__proto__(Function.prototype)中没有a方法
//F.__proto__.__proto__(Function.prototype.__proto__)为Object.prototype,a方法是a
F.b();//b
//F中没有
//F.__proto__(Function.prototype)中b方法
//练习2
var A = function() {};//A函数,具有prototype属性
A.prototype.n = 1;
var b = new A();//b是实例对象,b.__proto__指向A.prototype,是一个引用对象
//这里将A.prototype重新赋值,指向了一个新的对象
//但原来的对象还保持着b对他的引用,所以垃圾回收机制不会清除原来这个对象,b中的地址不会改成新的
A.prototype = {
n: 2,
m: 3
}
var c = new A();
console.log(b.n);//1
console.log(b.m);//undefined
console.log(c.n);//2
console.log(c.m);//3
var foo = {},
F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';
console.log(foo.a);//value a
//foo没有a属性
//foo.__proto__(Object.prototype)中a属性为:value a
console.log(foo.b);//undefined
//foo没有b属性
//foo.__proto__(Object.prototype)中没有b属性
//Object.prototype.__proto__为null
console.log(F.a);//value a
//F没有a属性
//F.__proto__(Function.prototype)没有a属性
//F.__proto__.__proto__(Function.prototype.__proto__)为Object.prototype
console.log(F.b);
//F没有b属性
//F.__proto__(Function.prototype)b属性为value b
//练习4
function A() {}
function B(a) {
this.a = a;
}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a); //1
//new A()没有a属性,该实例对象的__proto__即A.prototype.a = 1
console.log(new B().a);//undefined
console.log(new C(2).a);//直接找new C(2)对象中的a,是2
//练习5
console.log(123['toString'].length 123)//126
//练习6
function Fn() {
this.x = 100;
this.y = 200;
this.getX = function () {
console.log(this.x);
}
}
Fn.prototype.getX = function () {
console.log(this.x);
};
Fn.prototype.getY = function () {
console.log(this.y);
};
let f1 = new Fn;
let f2 = new Fn;
console.log(f1.getX === f2.getX);//这里getX找到的是每个实例对象身上的,false
console.log(f1.getY === f2.getY);//getY是原型对象身上的因此是共享的,true
console.log(f1.__proto__.getY === Fn.prototype.getY);//true
console.log(f1.__proto__.getX === f2.getX);//false
console.log(f1.getX === Fn.prototype.getX);//false
console.log(f1.constructor);//f1没有constructor属性,因此从f1.__proto__查找(Fn.prototype)上的constructor属性为Fn函数
console.log(Fn.prototype.__proto__.constructor);//(Object.prototype.constructor属性为Object函数)
f1.getX();//100
f1.__proto__.getX();//this指向原型对象,undefined
f2.getY();//
Fn.prototype.getY();//undefined
//练习7
function fun(){
this.a=0;
this.b=function(){
alert(this.a);
}
}
fun.prototype={
b:function(){
this.a=20;
alert(this.a);
},
c:function(){
this.a=30;
alert(this.a)
}
}
var my_fun=new fun();
my_fun.b();//"0"
my_fun.c();//"30"
记得 函数
和 对象
分别有隐式原型和显式原型就行了,原型链是顺着隐式原型找的,而隐式原型是指向其构造函数的显式原型的!!!
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgahiic
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24