ES5-20 复习

3-1

  • 变量单一声明方式
  • String Boolean undefined Number null
  • undefined == null
  • typeof(null) ‘object’
  • typeof(方法) ‘function’
  • typeof(+) +是运算符,不是数据类型 报错
  • +0 === -0 true
  • +Infinity == -Infinity false
  • NaN和谁都不等
  • 原始值没有属性 要打印属性、调用方法得经过基本包装类
  • 包装了还没有就没办法了,比如length属性
  • Boolean、Number包装了也没有length,打印就是undefined
  • 可以给包装类添加值以外的属性
  • 数字直接跟.有歧义,会认为是小数点
  • 三种基本包装类的toString、valueOf方法各不相干+
  • Function的toString、valueOf都返回函数体?
  • Object的toString
  • Array的toString,返回用逗号隔开
  • 要打印反斜杠,单双引号必须使用字符字面量,否则报错
  • 并且字符字面量还要用引号引起来
  • Object Array Function Date RegExp
  • 对象的属性是字符串类型

一些现象
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3-2

  • 目前证实会终止程序的有:语法错误、范围错误
  • 0/0 NaN
  • 1/0 +Infinity
  • 逗号运算符在表达式中只返回最后一个
  • ASCII码 0-255

在这里插入图片描述

3-3

  • 显示类型转换,Number对null、true、false,数组友好转010
  • Number对空数组和只有一个元素的数组友好
  • Number对undefined、1a不友好转NaN
  • ParseInt只对数字开头的友好
  • null、undefined既不大于也不小于更不等于0(隐式类型转换有坑)
    在这里插入图片描述
// 是否先对数组toString呢
console.log(Number([])) // 0
console.log(Number([1])) // 1
console.log(Number(['1'])) // 1
console.log(Number([1, 2, '3'])) // NaN
console.log(Number([1, 2, 3])) // NaN
console.log(Number({})) // NaN

3-4

  • 函数声明一定要有函数名,不然报错
  • 函数声明不能直接调用(无参),会报语法错误
  • 函数声明function a(){}(1),这样不报错,会认为(1)是表达式不是调用
  • 函数表达式可以()调用,是立即执行了
  • 函数表达式,function后的函数名在外部不可见,但是.name总能获得函数名(优先取function后的,没有就取表达式声明的变量名)
  • es5&&实参非undefined时形参、实参互相统一
  • es6、严格模式,形参、实参不统一
  • 函数是对象

3-5

  • 预编译:函数声明、函数整体提升
  • 变量声明,只有声明提升,赋值不提升,所以AO一开始是undefined
  • -1 + NaN + ‘’ 先做-1 + NaN得到NaN 再 +’’ 得到’NaN’

3-6

  • 看作用域链,函数AO、GO的this指向的是window
  • AO含thisarguments和变量声明、函数声明
  • 闭包是指有权访问另一个函数作用域中的变量的函数
  • 立即执行函数内将闭包添加到全局,无法销毁闭包对AO的引用
  • 闭包不是将被拉扯的AO放到全局!

3-7

  • 表达式会忽略函数名
  • 注意,此时GO里也没有b了
if (function b() { }) {
    console.log(typeof b) // undefined
}
console.log(b) // 报错
  • 解决闭包总是拿到AO在循环中最后的值,用IIFE并实时传值进去

3-8

  • 对象中的this指向对象本身
  • 构造函数,用new实例化后,函数内this指向实例
  • 不用new实例化,this指向window
  • 当构造函数return引用值时(除了this的函数、函数声明、对象、数组、Date…),返回引用值,若是原始值则忽略
  • 实例方法中的this,谁调用就指向谁
function MyTest(name) {
    this.name = name
    return this // 写或不写,返回的都是实例
}
console.log(new MyTest('Lee'))

3-10

在这里插入图片描述
在这里插入图片描述

  • 字面量方式改变构造函数prototype(指向新的对象)若在实例化前,则实例的__proto__会指向修改后的原型,若在实例化后,实例的__proto__还是指向默认的prototype
  • 若使用xx.prototype.属性 = 的修改方式(没有指向新对象),则实例访问到的属性也会跟着盖面
    在这里插入图片描述

4-1

  • 对于++ --,会计算再赋值,能让实例增添属性
  • 将null作为实例的原型,实例中将不包含任何属性!,将{}作为原型仍有__proto__
  • 因此,不是所有对象都继承Object.prototype
  • 手动增加的__proto__和自身的不一样,不能在手动增加的_proto__向上查找原型链
  • 原型链的终点是Object.prototype

4-2

  • 要在构造函数(而不是原型)中定义引用类型的属性(防止所有实例共享引用值)
  • 原型链实现继承(子类的原型指向父类的实例)的问题一:子类的实例可能会共享引用类型值(原本是父类构造函数中定义的属性)
  • 问题二:不能传参
  • 借用构造函数(子类构造函数内:父类构造函数call(this)),解决了原型链继承的问题,但函数无法复用超类型原型中的方法,对子类型不可见
  • 组合继承(原型链+借用构造函数),问题:超类的构造函数都执行了2次
  • Object.create(对象,{属性:属性描述符}),第二个参数将属性添加到新对象上
  • 寄生组合式继承用Object.create()指定新对象的__proto__,用**.constructor增强对象,结合call**
  • 圣杯模式实现继承:继承父类原型上的属性和方法,没有解决引用类型值问题,构造函数不能传值

4-3

  • 对象遍历(for (var key in obj))原型上的属性也会打印,用hasOwnProperty区分(严谨)
  • 数组遍历(for (ele val of arr))// ele是每一项arr的值
  • arguments.callee - 正在被执行的函数对象(在自启动函数中使用递归,且不需要函数名)
  • test.caller - test函数的调用者

for…of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句,可以由break, throw continue 或return终止。在这些情况下,迭代器关闭。

for…in不应该用于迭代一个关注索引顺序的 Array。

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES2015中,非对象的参数将被强制转换为一个对象。

4-4

  • 手写深拷贝,考虑原始值和引用值(区分数组和对象),结合递归

4-5

  • new Array()的参数用于设置数组长度,或设置数组(只传一个非数字值时)
  • 数组方法 - 继承了数组原型上的方法
  • push、unshift(返回值:执行了方法以后数组长度,可以传多个参数)
  • pop、shift(返回剪切掉的那个值)
  • splice(在哪个下标添加,返回值空数组)
  • 数组中认为最后一个元素的index是-1
  • sort是按照ASCII码排列的(未传参时)
  • sort(function(a,b){return 负数})

在这里插入图片描述

4-6

  • concat 返回值是拼接后的数组
  • slice[a,b)
  • join不传参数相当于toString!用逗号连接
  • split(a,b) 不传值,会将整个字符串放进数组;第二个参数b,是用a分割后截取b位
  • 类数组没有数组方法,因为没有继承Array.prototype,继承Object.prototype,类数组
  • 对象转类数组:给对象加splice属性,指向Array原型上的splice方法,对象的原型依然是Object.prototype (有什么意义
  • arguments对象的constructor是Object
  • obj实例调用push方法的原理,和length相关(并不一定是类数组)
  • length属性决定了类数组的长度,push开始的位置
  • 类数组转数组:Array.prototype.slice.call(arguments)、Array.from() (分别是ES5\ES6)
  • 箭头函数没有arguments

4-8

  • finally一定执行
  • throw要写在可能会出错的代码段前, catch(e) 可以抛出自定义信息e
  • JSON.parse()参数不能是空字符串或undefined,必须是JSON字符串
  • with可以改变作用域(因此会消耗性能)

严格模式下不能不写var
严格模式下,函数内部fn使用this指向undefined,但new fn实例化返回的this还是指向实例
严格模式下,函数参数不能重复
严格模式下,对象的属性不能重复
严格模式下,eval有自己的作用域,内部用var声明的变量不再是全局的

Duplicate property name in object literal is allowed in ES6 strict mode

常识归类

  • 1不是质数 2是
  • 质数是只能被1和自己整除的数
  • 斐波那契数列,前2项是1,之后每项为前两项之和
  • ASCII码charCode范围在0-255,每个字符1字节,从256开始的内容每个2字节
  • 闰年(整除4&&不能整除100 || 整除400)

关于this

  • 在函数内部,this的值取决于函数被调用的方式。this值没被设置时(未使用call、apply)默认指向window
  • call、apply传null 和 undefined 会被转换为全局对象。原始值如 7 或 ‘foo’ 会使用相应构造函数转换为对象。
  • bind的this绑定只生效一次:this将永久地被绑定到了bind的第一个参数
  • 当函数作为对象里的方法被调用时,this 被设置为调用该函数的对象
  • 当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。
  • Object.assign是浅拷贝,JSON.parse(JSON.stringify)是深拷贝
var obj = {
    count: {
        a: 1,
        b: 2
    }
}
var obj1 = Object.assign({}, obj)
obj1.count.a = 100 
console.log(obj.a) // 100

// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
typeof new Boolean(true) === ‘object’;
typeof new Number(1) === ‘object’;
typeof new String(‘abc’) === ‘object’;

关于valueOf

JavaScript调用valueOf方法将对象转换为原始值。
默认情况下,valueOf方法由Object后面的每个对象继承。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则valueOf将返回对象本身。
JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 控制台为什么有这样的迷惑行为…因为自己不小心重写了Object原型上的valueOf方法 = =,以下反面教材不要看
  • 但是为什么Array、Function也受影响呢?原因是他们都是同一个valueOf

The Array prototype object does not have a valueOf property of its own;however,it inherits the valueOf property from the standard built-in Object property Object.
The Function prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

关于隐式类型转换

关系操作符(< > ≥ ≤)

  1. 数字比较比数字
  2. 字符串比较比字符编码值(大写字母<小写字母)
  3. 有一个数字,另一个也转数字(null转0,undefined转NaN,除了和0不能比,null和非0能比较)
  4. 有一个布尔值,把它转为数字
  5. 有一个对象,调用valueOf,没有则调用toString

相等和不相等(== !=)

  1. 有一个布尔值,把它转为数字
  2. 字符串和数字,先将字符串转数字
  3. 有一个对象,调用valueOf得到基本类型值再走以上规则(怎么得到基本类型值,这里有文章)
  4. null、undefined在比较相等性前不得转换(所以和任何比较==都是 false)
  5. 都是对象,比较是不是相同指向
    在这里插入图片描述
  • 关系、相等运算符掺杂了其他运算符,有优先级
    根据运算符优先级 ,! 的优先级是大于 == 的
[] == true // false
[] == ![] // true
{} == !{} // false
console.log({ a: 1 } == '[object Object]') // true
console.log({ a: 1 } == true) // false
console.log([] == '[object Array]') // false 数组toString是空字符串
console.log([] == '') // true
console.log([] == 0) // true
console.log([] == false) // true
const number1 = new Number(3);
const number2 = new Number(3);
number1 == 3;         // true
number1 == number2;   // false
// [] == ! []   ->   [] == false  ->  [] == 0  ->   '' == 0   ->  0 == 0   ->  true

ECMA类型转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值