ES62构造函数和原型、对象

创建对象的方法

// 使用new Object创建对象
let obj = new Object();
// 使用对象字面量创建对象
let obj2 = {};
//  使用构造函数创建对象
function Star(username, age) {
  this.username = username;
  this.age = age;
  this.sing = function() {
    console.log("song");
  };
}

let p = new Star("jack", 19);
p.sing();
实例成员和静态成员

//  使用构造函数创建对象
function Star(username, age) {
  // 构造函数内部通过this添加的成员,称为实例成员,只能通过实例化的对象来访问
  this.username = username;
  this.age = age;
  this.sing = function() {
    console.log("song");
  };
}

let p = new Star("jack", 19);
p.sing();
// 在构造函数本身添加的成员就是静态成员
Star.sex = "男";
// 只能通过构造函数来访问,不能通过对象来访问
console.log(Star.sex);
构造函数存在浪费内存的问题

构造函数通过原型分配的函数式所有对象共享的,这个对象的所有属性方法,都会被构造函数所拥有。

把不变的方法直接定义在prototype对象上,所有的对象的实例就可以共享这些方法

function Star(username, age) {
  // 公共属性定义到构造函数里
  this.username = username;
  this.age = age;
}
// 公共方法放到原型对象上
// Star.prototype.sing = function() {
//   console.log("song");
// };
// Star.prototype.movie = function() {
//   console.log("movie");
// };
Star.prototype = {
  // 如果修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动指向原来的构造函数
  constructor: Star,
  sing: function() {
    console.log("song");
  },
  movie: function() {
    console.log("movie");
  }
};
// 对象都会有一个__proto__指向构造函数的prototype原型对象,
// 对象之所以能够使用构造函数的prototype原型对象的方法,就是因为有__proto__原型的存在。
// 虽然没有定义p对象的方法,但是系统自动为p对象身上添加__proto__指向构造函数的原型对象。
let p = new Star("jack", 19);
// 方法查找规则:首先查找p对象有没有sing方法,有就执行sing方法,没有就去构造函数原型上查找sing方法
p.sing();
// console.dir(Star);
// console.log(p.__proto__ === Star.prototype);
console.log(Star.prototype.constructor);
console.log(p.__proto__.constructor);
console.log(Star.prototype);
console.log(p.__proto__);
原型链

function Star(username, age) {
  this.username = username;
  this.age = age;
}
Star.prototype.sing = function() {
  console.log("song");
};
let p = new Star("jack", 19);
// 只要是对象就有有__proto__原型,指向原型对象
console.log(Star.prototype);
// 在Star原型对象里面的__proto__原型指向的是Object.prototype
console.log(Star.prototype.__proto__ === Object.prototype);
// Object.prototype原型对象里的__proto__原型指向为null
console.log(Object.prototype.__proto__);
对象成员查找规则

function Star(username, age) {
  this.username = username;
  this.age = age;
}
Star.prototype.sing = function() {
  console.log("song");
};
// Star.prototype.sex = "man";
Object.prototype.sex = "woman";
let p = new Star("jack", 19);
p.sex = "man";
// 访问对象的属性方法时,(就近原则)先查找对象自身有没有该属性,没有就找prototype原型对象上的,再没有就找Object的原型对象
console.log(p.sex);
原型对象this指向

// 在构造函数中,里面的this指向的是实例对象p
function Star(username, age) {
  this.username = username;
  this.age = age;
}
let that;
Star.prototype.sing = function() {
  console.log("song");
  that = this;
};
let p = new Star("jack", 19);
p.sing();
// 原型对象函数里的this指向的是实例对象p
console.log(that === p); // true
利用原型对象扩展内置对象方法

Array.prototype.sum = function() {
  let sum = 0;
  for (let i = 0; i < this.length; i++) {
    sum += this[i];
  }
  return sum;
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr.sum());
console.log(Array.prototype);
call 调用这个函数,并修改函数运行时的this指向

function fn(x, y) {
  console.log("hello");
  // 指向window
  // console.log(this);
  console.log(x + y);
}
let o = {
  name: "andy"
};
// 1. call()可以调用函数
// fn.call();
// 2. 改变这个函数的this指向,在函数里面指向了o这个对象,并传递了参数
fn.call(o, 1, 2);
借用父构造函数来继承属性方法

// 借用父构造函数来继承属性
function Father(username, age) {
  // 里面的this指向的是父构造函数的对象实例
  this.username = username;
  this.age = age;
}
Father.prototype.money = function() {
  console.log("money");
};
function Son(username, age, score) {
  // 里面的this指向的是子构造函数的对象实例,使用call之后,父构造函数里面的this变成了子函数里的this
  Father.call(this, username, age);
  this.score = score;
}
// 继承Father的方法,但不会影响Father类
Son.prototype = new Father();
// 如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的构造函数
Son.prototype.constructor = Son;
// 子构造函数的独有方法,不会改变影响父类
Son.prototype.exam = function() {
  console.log("exam");
};
let p = new Son("jack", 19, 100);
p.money();
p.exam();
console.log(p);
console.log(Father.prototype);
console.log(Son.prototype.constructor);
类的本质
其实还是一个function

class Star {}
console.log(typeof Star); // function
Foreach

let arr = [1, 2, 3];
let sum = 0;
arr.forEach((value, index, array) => {
  // console.log("每个数组元素", value);
  // console.log("每个数组元素的索引号", index);
  // console.log("数组本身", array);
  sum += value;
});
console.log(sum);
filter

let arr = [32, 18, 78, 40, 11, 13];
// filter遍历,通过筛选返回一个新的数组
let temp = arr.filter((value, index) => {
  // return value >= 20;
  return value % 2 === 0;
});
console.log(temp);
some

let arr = [32, 18, 78, 40, 11, 13];
// some 查找数组中是否有满足条件的元素(数组当前项的值,索引,数组本身),
// 返回一个布尔值,如果找到就返回为true,找到第一个满足的就终止循环
let flag = arr.some((currentValue, index, arr) => {
  // return currentValue % 2 === 0;
  return currentValue > 100;
});
console.log(flag);

filter  some区别

filter查找满足的元素,返回一个数组,把所有满足的元素返回来

some查找满足的元素,返回一个布尔值,找到第一个就终止

trim

let str = "  2  2  4  ";
console.log(str.trim());
console.log(str.trimstart());
console.log(str.trimLeft());
Object.defineProperty

let obj = {
  id: 1,
  name: "jack",
  age: 19
};
/**
 * obj 目标对象  prop 需定义或修改属性的名字  descriptor 目标属性所拥有的特性
 * Object.defineProperty(obj, prop, descriptor);
 * **/
// 修改存在的属性
Object.defineProperty(obj, "age", {
  value: 20
});
// 是否允许修改属性值,认为false
Object.defineProperty(obj, "id", {
  writable: true
});
obj.id = 2;
// 没有就是新增属性,定义一个num的属性,值为1000
Object.defineProperty(obj, "num", {
  value: 1000,
  // 是否可以重写,认为false
  writable: false,
  // enumerable为false,则不会被枚举,认值是false
  enumerable: false,
  // configurable 目标属性是否可以删除或再次修改认为false
  configurable: false
});
console.log(obj); // {id: 2, name: "jack", age: 20, num: 1000}
console.log(Object.keys(obj)); // ["id", "name", "age"]
delete obj.num;
console.log(obj); // num 不可被删除
// 上面设置了num不可被再次定义,所以再次修改就不可以了
Object.defineProperty(obj, "num", {
  value: 1000,
  writable: true,
  enumerable: true,
  configurable: true
});
Object.keys()

let obj = {
  id: 1,
  name: "jack",
  age: 19
};
/**
 * Object.keys()获取对象自身所有的属性
 * 类似于for..in
 * 返回一个属性名组成的数组
 * **/
let arr = Object.keys(obj);
// 遍历属性名
arr.forEach(value => {
  console.log(value);
});

 

ronle 发布了2 篇原创文章 · 获赞 0 · 访问量 81 私信 关注

相关文章

原文连接:https://www.cnblogs.com/dupd/p/5951311.htmlES6...
以为Es6,javascript第一次支持了module。ES6的模块化分为导...
视频讲解关于异步处理,ES5的回调使我们陷入地狱,ES6的Prom...
TypeScript什么是TypeScript?TypeScript是由微软开发的一款开...
export class AppComponent { title = 'Tour of heroes...
用 async/await 来处理异步昨天看了一篇vue的教程,作者用as...