批改状态:合格
老师批语:理解到位,原型链我们一般用__proto__来称呼,浏览器[[prototype]],存储着对象的构造函数的prototype
var Vehicle = function () {this.price = 1000;};
var Vehicle = function () {this.price = 1000;return 1000;};(new Vehicle()) === 1000// false
上面代码中,构造函数 Vehicle 的 return 语句返回一个数值。这时,new 命令就会忽略这个 return 语句,返回“构造”后的 this 对象
如果 return 语句返回的是一个跟 this 无关的新对象,new 命令会返回这个新对象,而不是 this 对象。这一点需要特别注意
var Vehicle = function (){this.price = 1000;return { price: 2000 };};(new Vehicle()).price// 2000
上面代码中,构造函数 Vehicle 的 return 语句,返回的是一个新对象。new 命令会返回这个对象,而不是 this 对象
如果对普通函数(内部没有 this 关键字的函数)使用 new 命令,则会返回一个空对象
function getMessage() {return 'this is a message';}var msg = new getMessage();msg // {}typeof msg // "object"
var Vehicle = function () {this.price = 1000;};var v = new Vehicle();
每个函数都有一个 prototype 属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用 new 操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法
每个函数都有一个 prototype 属性,指向一个对象
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上
原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象
所有对象都有自己的原型对象(prototype),任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”:对象到原型,再到原型的原型
原型链的尽头就是 null
prototype 对象下有个 constructor 属性,默认指向 prototype 对象的构造函数
公有是指,在外部环境中可以获取的,可以直接通过实例对象用”.”运算符操作获得。(在构造函数中用 this 进行声明)
私有是指,在外部环境中不能直接访问,该属性/方法只能在对象的构造函数内访问。(声明在构造函数里的变量和方法,没有用到 this)
静态是指,属性/方法是归属于构建函数/类的,而非实例对象。可以直接通过类名来调用得到func.静态方法名 = function () {....}; func.静态方法名()
共享是指,实例对象之间,共享属性和方法,借助向原型对象添加属性和方法,可以实现继承
super 这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同
super 作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类
<script>// 构造函数let Animal = function (name) {this.height = 120;this.name = name;};// 通过原型对象给实例添加共享方法Animal.prototype.walk = function () {return `${this.name} 在缓慢行动`;};Animal.prototype.foot = function () {return this.name + "有四条腿";};let tigger = new Animal("tigger");console.log(tigger);console.log(tigger.foot());console.log(tigger.walk());let cat = new Animal("cat");console.log(cat);console.log(cat.walk());</script>

<script>// class用法class animal {// 私有属性 只能在类内部使用#foot = 4;// constructor 引用构造函数constructor(name) {// this指向animal的实例化对象// 公有属性this.name = name;}// 共享方法/属性,和构造函数的prototype对象的一样walk() {return this.name + "开始行走";}run() {return this.name + "跑向猎物";}// 静态只需要在前面机上static关键字// 如果静态方法包含this关键字,这个this指的是类,而不是实例static eat() {console.log("快跑野兽要进食了");}}// 静态属性animal.live = "live";// new一个对象let tigger = new animal("tigger");// 调用静态方法animal.eat();console.log(tigger.walk());console.log(tigger.run());console.log(animal.live);// 继承class Dog extends animal {constructor(name, color) {// 子类必须使用一次super函数super(name);this.color = color;}growl() {console.log("growl");}// 访问器属性 get set方法读写get dogColor() {console.log(this.color);}set reColor(value) {this.color = value;}}// 父类的静态方法会也被子类继承Dog.eat();let lucky = new Dog("lucky", "black");console.log(lucky.walk());lucky.reColor = "white";lucky.dogColor;</script>

从数组和对象中提取值,对变量进行赋值,这被称为解构
let [a, b, c] = [1, 2, 3];// 如果解构不成功,变量的值就等于undefinedvar [j, q, k] = [11, 12];console.log(j, q, k);// 可以使用默认的值来避免结构不成功造成的undefinedvar [j, q, k = 13] = [11, 12];console.log(j, q, k);// 使用...rest参数把多余的值,放入一个数组let [z, x, ...v] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];console.log(z, x, v);// 两个变量交换值很方便let [one, two] = [10, 100];console.log(one, two);one = one + two;two = one - two;one = one - two;console.log(one, two);// 上面方法太麻烦了// 再用解构的方法变回去[one, two] = [two, one];console.log(one, two);// 对象解构let { name, age, sex } = { name: "terry", age: 28, sex: "male" };console.log(name, age, sex);// 更新使用括号当作表达式({ name, age, sex } = { name: "marry", age: 26, sex: "female" });console.log(name, age, sex);// 变量名冲突({name: nickname,age,sex,} = { name: "jordan", age: 36, sex: "female" });console.log(nickname, age, sex);// 函数的参数解构function pValues({ name, age, sex }) {console.log(name, age, sex);}let userValues = { name: "ice", age: 26, sex: "male" };pValues(userValues);

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号