前端复盘专题(一)

619 阅读4分钟

一、基础知识

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
booleanboolean
stringstring
numbernumber
object、nullobject
functionobject
symbolsymbol

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还未找到就返回falseimage.png

4.数值转换

显式转换

将非数值转换为数值: Number()、ParseInt()、ParseFloat()

ParseInt()转换规则: 从第一个非空格字符开始转换,如果第一个转换的字符不是数值、+、-则返回naN,直至字符串末尾,所以空字符串也会返回naN。

ParseFloat()转换规则: 从第一个非空格字符开始转换,如果第一个转换的字符不是数值、+、-则返回naN,直至字符串末尾,所以空字符串也会返回naN,只有第一个小数点是有效的后面的都会忽略。

函数参数参数-->返回值true/false数值nullundefined字符串含数值字符串含数值和+、-字符串含浮点数字符串含十六进制数空字符串字符串前面的都不含
Number()任何数据类型1/0直接返回0naN十进制数十进制数浮点数十六进制数0naN
ParseFloat()字符串1/0直接返回0naN十进制数十进制数浮点数十六进制数0naN

隐式转换

换为字符串:

显式转换

toString():null和undefined除外,每个值都有toString()属性。

string()转型函数:null和undefined返回"null"和"undefined",其他值调用toString()。

隐式转换

用+给一个值加上一个" "

5. for..in 与 for..of

for in 和 for of 的异同点

比较for..infor..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));