一、基础知识
1.var与let/const区别
1.作用域不同
var :函数作用域
var定义的变量作用域为包含它函数的局部变量,改变量在函数退出时被销毁。(所以在函数内部用var定义的变量在函数外部是访问不到的)
let和const:块级作用域
let和const定义的变量作用域为包含它的代码块。
2.var声明的变量会变量提升,let和const声明的不会
3.var可以重复声明一个变量,let和const重复声明一个变量会报错,const声明变量的同时要赋初值。
4.let、const声明的全局变量不会成为window对象的属性,var声明的变量会
2.typeof
typeof 检测值 | 返回值 | 未初始化、未声明变量 | undefined | boolean | boolean | string | string | number | number | object、null | object | function | object | symbol | symbol |
---|
typeof
原理:
js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息?
000:对象
010:浮点数
100:字符串
110:布尔
1:整数
but, 对于 undefined 和 null 来说,这两个值的信息存储是有点特殊的。
null:所有机器码均为0
undefined:用 −2^30 整数来表示
所以,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。
3.instanceof原理
每个 JavaScript 对象均有一个隐式的 proto 原型属性,而显式的原型属性是 prototype。instanceof
原理就是先拿到右边的prototype属性,在依次检查左边原型链上的__prop__属性,直到有相等的就返回true
,直到null还未找到就返回false
。
4.数值转换
显式转换
将非数值转换为数值:
Number()、ParseInt()、ParseFloat()
ParseInt()转换规则: 从第一个非空格字符开始转换
,如果第一个转换的字符不是数值、+、-
则返回naN
,直至字符串末尾,所以空字符串也会返回naN。
ParseFloat()转换规则: 从第一个非空格字符开始转换
,如果第一个转换的字符不是数值、+、-
则返回naN
,直至字符串末尾,所以空字符串也会返回naN,只有第一个小数点是有效的后面的都会忽略。
函数 | 参数 | 参数-->返回值 | true/false | 数值 | null | undefined | 字符串含数值 | 字符串含数值和+、- | 字符串含浮点数 | 字符串含十六进制数 | 空字符串 | 字符串前面的都不含 | Number() | 任何数据类型 | 1/0 | 直接返回 | 0 | naN | 十进制数 | 十进制数 | 浮点数 | 十六进制数 | 0 | naN | ParseFloat() | 字符串 | 1/0 | 直接返回 | 0 | naN | 十进制数 | 十进制数 | 浮点数 | 十六进制数 | 0 | naN | ### 隐式转换 |
---|
换为字符串:
显式转换
toString():null和undefined除外,每个值都有toString()属性。
string()转型函数:null和undefined返回"null"和"undefined",其他值调用toString()。
隐式转换
用+给一个值加上一个" "
5. for..in 与 for..of
for in 和 for of 的异同点
比较 | for..in | for..of | 不同点 | 可以遍历普通对象 遍历出数组的原型对象 可以遍历出数组自身属性 遍历出来的值是 key 不可以遍历 map/set 不可以迭代 generators IE 支持 | 不能遍历普通对象 不会遍历出原型对象 不会遍历自身属性 遍历出来的值是 value 可以遍历 map/set 可以迭代generators IE 不支持 | 相同点 | 可以遍历数组 可以 break 中断遍历 | 可以遍历数组 可以 break 中断遍历 |
---|
二、 手写实现函数
1.instanceof
function myInstanceof (left, right) {
const RigPro = right.prototype
while (true) {
if (left === null) {
return false
}
if (left.__proto__ === RigPro) {
return true
}
left = left.__proto__
}
}
2.new关键字
new关键字做了什么:
1.在内存中创建一个新对象
2.将这个新对象内部的__proto__
属性赋值为构造函数的prototype属性。
3.构造函数的内部的this被赋值为这个新对象(即this指向新对象)
4.执行构造函数内部的代码(给新对象添加属性)
5.如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
function myNew (func, ...args) {
// myNew函数接收两个参数:构造函数,构造函数所需要的参数
const newObj = {}
newObj.__proto__ = func.prototype
const obj = func.call(newObj, ...args)
if( ( typeof obj == 'object' || typeof obj == 'function' )&& typeof obj !== 'null' ) {
return obj
}
return newObj
}
function Person(name, age) {
this.name = name
this.age = age
}
const p1 = myNew(Person, 'lili', 18)
console.log(p1);
3.call函数
Object.prototype.myCall = function (context, ...args) {
// 当context为null或undefined时,将context赋值为window
context = context || window
// 新建一个fn属性,用来保存当前调用这个函数的this
context.fn = this
const result = context.fn(...args)
delete context.fn
return result
}
const p1 = {
add: function add (a, b) {
return a + b
}
}
console.log(p1.add.myCall(p1, 1, 2));
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!