• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

JS红宝书复习章八对象,类和面向对象编程

武飞扬头像
想要变得厉害的Yingying
帮助1

Object.assign()

该函数接收两至多个参数:第一个参数为目标对象,之后的参数作为源对象,将源对象中可枚举和自有属性复制到目标对象;

  1. 对每个源对象执行的是浅复制
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
系列文章
更多 icon
同类精品
更多 icon
继续加载