1.JS的数据类型有哪些?
共8种
6种旧的:数字umber、字符串string、null、undefined、布尔bool、对象object
2种新的:bigint,只能表示整数,防止精度不够造成数据储存出错、symbol
2.说明是原型链
答题范式:大化小,抽象化具体。
原型链涉及到的概念挺多的,我举例说明一下:
(是什么) 数组a,其隐藏属性为a.__proto__,它等于Array.prototype。Array.prototype的隐藏属性为Array.prototype__proto__,它等于Object.prototype。这就构成了一条原型链。
(怎么做) 我们可以用 a=Object.create(f) 或者a=new f() 将a.__proto__原本的Object.prototype替换为f,同时f也有自己的隐藏属性,且 f__proto__=Object.prototype 来构造一个原型链。
(解决了说明问题) 可以在没有class的情况下实现继承。由于a.__proto__===Array.prototype,a通过实例化,得到了Array.prototype内的属性,而Array.__proto__===Object.prototype, a 就通过继承,得到了Object.prototype的属性。
(优点)简单优雅
(缺点)与class相比,不支持私有属性,且写法也会有些复杂。
(如何解决缺点)用class
JS 中 __proto__ 和 prototype 存在的意义是什么?www.zhihu.com/question/56…
3.代码中的this是多少
代码转换:
①f(p) => f.call(this,p),f前没有东西,this默认为undefind,如果不限制,浏览器会将undefined转换为window。
②a.b.c.f(p) => f.call(a.b.c,p),此时this为a.b.c
总之,this为用call调用函数时的第一个参数。
注意一下,箭头函数没有this。
4.JS的new做了什么
1.创建临时对象
2.绑定原型
3.执行构造函数
4.返回临时对象
5.指定this=临时对象
JS 的 new 到底是干什么的? zhuanlan.zhihu.com/p/23987456
5.JS的立即执行函数
(是什么) 声明一个匿名函数,然后立即执行它。这个做法就是立即执行函数。
(怎么做) 写法:
( function (){ 语法 } () ) 用括号把整个表达式包起来。
( function (){ 语法 }) () 用括号把函数包起来。
!function (){ 语法 } () 加!,也可以用+/-/~
void function (){语法} () 加void,也可以用new
var x = function (){语法} ()
(解决了说明问题) :在ES6之前,用它来创建局部变作用域。而在这个局部作用域可以创建局部变量。(ES6创建局部变量,可以用{ let a } ,不能用var)
(优点) 兼容性好。
(缺点) 不美观。
如何解决:用ES6的语法,不要用立即执行函数。
6.什么是闭包?怎么用?
(是什么) 是一种语法特性。函数 访问 函数外的 自由变量(不是全局变量,全局变量任何函数都能访问)
(怎么做)
var die2 = function add (){let lives = 3;const die = ()=>{livers-+1;} return die;}标黄位置即为闭包语法
die2()//相当于执行了livers-+1;
(解决什么问题)
1.避免污染全局环境(因为用的是局部变量)。 2.提供对局部变量的间接访问。 3.维持变量,使其不被垃圾回收。
(优点) 简单好用。
(缺点) 使用不当会造成内存泄漏。
(如何克服缺点) 慎用,少用。
7.JS如何实现类
(所有的函数都有一个prototype.constructor,且等于函数本身,即x.prototype.constructor===x,因此在创建一个函数时,给它的prototype赋值尽量不用x.prototype={a:'xxx',b:'xxx'},会覆盖掉prototype.constructor,有可能会出bug,最好写作x.prototype.a='xxx')
举例:以下两种都是实现类的方法。
使用 原型 来写。对象本身的属性写在构造函数内,共有属性写在原型内。
function Dog(){
this.name = name
this.color = 'black'
}
Dog.prototype.say = function(){
console.log(`汪汪汪,我是${this.name}`)
}
Dog.prototype.kind = '狗'
用 class 来写。把对象本身的属性写在constructor内,共有属性写在constructor外。
class Dog{
kind = '狗'
constructor(name){
this.name = name
this.color = black
}
say(){
console.log(`汪汪汪,我是${this.name}`)
}
}
两种方法不等价。
8.如何实现继承
1.通过原型链:构建一个原型链.
例如Dog.prototype.__proto__=Animal.prototype。Dog就继承了Animal的属性。但是不推荐这个语法,有可能出错,可以用Dog.prototype = new Animal()但new会执行Animal()中的构造函数,为了避免执行构造函数,可以先构造一个空函数,指定空函数的prototype和Animal.prototype相等即可。
var fn = function(){}
fn.prototype = Animal.prototype
Dog.prototype = new fn()即可。
关键代码:要在Dog函数内调用Animal.call(this,'black'),第二个就是上面的三行。
2.通过class
class Dog extends Animal{
constructor(name){
super('black')
this.name = name }
}
关键字:extends,super()且super()得先于自己的属性前,比如this.name前调用,否则会错。super()内的参数是要被继承的类中的constructer(xxx){}中的xxx。