ES5 学习笔记 —— 零散知识点(一)

154 阅读6分钟

new 关键字

new 在执行时会做四件事

  1. 在内存中创建一个新的空对象
  2. this 指向这个新的对象
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法
  4. 返回这个新对象(所以构造函数里面不需要 return

构造函数和原型

构造函数

  • JavaScript 的构造函数中可以添加以下成员,可以在构造函数本身上添加,也可以在构造函数内部的 this 上添加。
  • 通过这两种方式添加的成员,分别成为 静态成员实例成员
    • 实例成员:在构造函数内部创建的对象称为 实例成员只能由实例化的对象来访问
    • 静态成员:在构造函数本身上添加的成员称为 静态成员只能由构造函数本身来访问

image.png

构造函数原型 prototype

  • 构造函数通过原型分配的函数是所有对象共享的
  • JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。注意这个 prototype 就是就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有
  • 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法

image.png

对象原型 __proto__

  • 对象都会有一个属性 __proto__ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型对象的存在
  • __proto__ 对象原型和原型对象 prototype 是等价的
new Star(){}

let ldh = new Star()

Star.prototype === ldh.__protot__ // true
  • __proto__ 对象原型的意义就在于为对象的查找机制提供一个方法,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype

constructor 构造函数

  • 对象原型(__proto__)构造函数(prototype)原型对象 里面都有一个属性 constructor 属性,contructor 我们称为构造函数,因为它指回构造函数本身
  • constructor 主要用于记录该对象引用与哪个构造函数,它可以让原型对象重新指向原来的构造函数

image.png

image.png

  • 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用 constructor 指回原来的构造函数

image.png

构造函数、实例、原型对象 三角关系

  • 每一个函数都有一个 prototype 属性,指向另一个对象
  • 每个对象都会有一个 __proto__ 属性,指向构造函数的 prototype 原型对象
  • Student.prototype === Jane.__proto__
  • prototype__proto__ 指向的其实是同一个对象
  • 这个对象里有一个 constructor 属性,指回构造函数本身
  • 图中,__proto__ 的连续指向,构成了原型链。当需要按照原型链查找时,其实就是沿着 __proto__ 去查找

image.png

原型对象的 this 指向

  1. 在构造函数中,里面的 this 指向的是 对象实例
  2. 原型对象函数里面的 this 指向的是 实例对象

image.png

ES5 实现继承

  • ES6 之前并没有给我们提供 extends 继承,我们可以通过 构造函数+原型对象模拟实现继承,被称为组合继承

    1. 借用构造函数继承父类型属性
      • 核心原理:通过 call() 把父类型的 this 指向子类型的 this,这样就可以实现子类型继承父类型的属性

    image.png

    1. 借用原型对象继承父类型方法
      • 核心原理:将父构造函数 new 出的实例 (new Father())赋值给子构造函数的原型对象,并且将子构造函数的原型对象中的 constructor 指回原来的构造函数(子构造函数

    image.png

图解 ES5 的继承

image.png

类的本质

  1. class 本质还是 function
  2. 类的所有方法都定义在类的 prototype 属性上
  3. 类创建的实例,里面也有 __proto__ 指向类的 prototype 原型对象
  4. 所以 ES6 的类它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
  5. 所以 ES6 的类其实就是语法糖
  6. 语法糖:语法糖就是一种便捷写法,简单理解,有两种方法可以实现同样的功能,但是一种写法更加清晰、方便,那么这个方法就是语法糖

ES6 之前通过 构造函数+原型 实现面向对象编程
ES6 通过 实现面向对象编程

image.png

内置对象

  • 内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
  • JavaScript 提供了多个内置对象:MathDateArrayString

Math

Math.PI                 // 圆周率
Math.floor()            // 向下取整
Math.ceil()             // 向上取整
Math.round()            // 四舍五入版 就近取整 注意 -3.5 结果是 -3
Math.abs()              // 绝对值
Math.max() / Math.min() // 求最大和最小值

Date

  • 获得 Date 总的毫秒数(时间戳),就是我们现在的时间,距离 1970.1.1 总的毫秒数
    1. 通过 valueOf()getTime()
    var date = new Date();
    console.log(date.valueOf());
    console.log(date.getTime())
    
    1. 简单的写法
    var date1 = +new Date();
    
    1. H5 新增的方法
    console.log(Date.now());
    

Array

  • 监测是否为数组
    1. instanceof 运算符,它可以用来监测是否为数组
    var arr = [];
    var obj = {};
    console.log(arr instanceof Array);
    console.log(obj instanceof Array);
    
    1. Array.isArray(参数),H5 新增的方法,ie9 以上版本支持
    console.log(Array.isArray(arr));
    console.log(Array.isArray(obj));
    
  • 数组排序(冒泡排序)
var arr1 = [13, 4, 77, 1, 7];
arr1.sort(function(a, b) {
    return a - b; // 升序的顺序排列
    // return b - a; // 降序的顺序排列
})

String

  • 根据位置返回字符
    1. charAt(index) - 返回指定位置的字符(index 字符串的索引号)
    2. charCodeAt(index) - 获取指定位置处字符的 ASCII 码(index 索引号)
    3. str[index] - 获取指定位置处字符
  • 截取字符串
    1. substr(start, length) - 从 start 位置开始(索引号),length 取的个数
    2. slice(start, end) - 从 start 位置开始,截取到 end 位置,end 取不到(他们俩都是索引号)
    3. substring(start, end) - 从 start 位置开始,截取到 end 位置,end 取不到

堆和栈

  • 栈:由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。简单数据类型存放到栈里面
  • 堆:存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放到堆里面

注意:JavaScript 中没有堆栈的概念,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式,便于将来学习其他语言