1. {}和[]的valueOf和toString的结果是什么?
{} 的 valueOf 结果为 {} ,toString 的结果为 "[object Object]"
[] 的 valueOf 结果为 [] ,toString 的结果为 ""
也就是说:{} 和[]valueOf 结果为是他们本身
2. 为什么 [].toString是""?
JavaScript的许多内置对象都重写了toString。
1.Array的toString是:每个元素转换为字符串,两个元素之间用英文逗号隔开连接。
空数组没有元素转为空字符串 ""
2.Boolean的toString是:如果布尔值是true,则返回"true"。否则返回"false""。
3.Date的toString是:返回日期的文本。
3. toString方法的三个作用
1.返回一个【表示对象】的【字符串】 "[object 类型]"
2.检测对象的类型
Object.prototype.toString.call(arr)==="[object Array]"
3.返回该数字对应进制的字符串。
console.log(10.toString(2)) //10专为为2进制'1010'
在js中包含2进制,8进制,10进制,16进制。
4. js几种模块的规范
有四种成熟的模块规范。
1.CommonJS。通过require来引入,通过module.exports输出接口。
他是服务端的解决方案,以同步的方式来引入模块。
如果是在浏览器端,模块的加载使用网络,同步的方式就不太好。
2. AMD方案他采用的是异步加载模块。
模块的加载不影响后面语句的执行。
所有依赖这个模块的语句都在载一个回调函数中,
等待模块加载完成后再执行回调函数
require.js 实现了 AMD 规范。
3. CMD方案:异步加载的方式来加载模块
sea.js 实现了 CMD 规范
第4种方案是 ES6 提出的方案,使用 import 和 export 的形式来导入导出模块。
5. undefined 和 undeclared 的区别
undefined:在作用域中申明变量但是没有赋值,
var a; 当我们访问a就是undefined
undeclared:在作用域中没有申明过的变量;如 b;
当我们访问b就是 undeclared;
控制台报错:b is not defined
其实“ undefined” 和“ is not defined ”是两码事。
并且typeof对undefined 和 undeclared 变量返回的都是undefined。
6. javascript 创建对象的几种方式?
1.字面量的方式去创建对象。 var person1={ age:12,name:'zs'}
2.使用new字符创建对象
var person2=new Object();
person2.name='柯南'
【虽然上面这2种都可以去创建对象
但是我们创建出来的对象我们无法判断是什么类型。
】
3.自定义构造函数创建对象
function Person(name,age,){
this.name=name;
this.age=age;
this.say=function(){
console.log("我叫",name)
}
}
let per1=new Person('柯南',19,'男');
//这样就可以判断属于什么类型
console.log(per1 instanceof Person);//true
4.工厂模式创建对象,【工厂模式new一个obj,然后设置这个obj的相关属性,最后再然后】
function createObj(age) {
let obj=new Object();
obj.age=age;
obj.sayHi=function(){
console.log(obj.name)
}
return obj;
}
let per=createObj('司藤',200)
[kɑːmən ] CommonJS 普遍的
[e k s po s] exports 输出
[舍 | si] sea 海洋
undeclared 未承认的,未申明的 [ʌn dɪ k li ə d]
7.当我们new一个对象的时候做了四件事情
1.开辟空间存储当前对象
2.把this设置为当前对象
3.设置属性和方法
3.把this对象返回
8.防抖
当持续触发事件时,【一定时间段内】该事件没有被触发。
事件处理函数才会被执行一次。
如果设定的时间到来之前,又触发了事件,就重新开始延时。
9.函数节流
在规定的单位时间内,只能够触发一次。
也就是在规定的时间内某事件被多次触发,那么只能够生效一次.
10.什么是回调函数 ? 缺点
回调函数是一段可执行的代码,
它作为一个参数传递给其他的代码.
其作用是在需要的时候方便调用这段(回调函数)代码。
回调函数有一个致命的弱点,
在多个事件存在依赖性,
就是容易写出回调地狱(Callback hell)。
11.什么是对象解构?
对象析构是从对象或数组中获取值的一种新的、更简洁的方法。
当我们的对象有很多的属性和方法,通过对象点属性的时候会很麻烦
如果使用对象解构,就会变得非常的简单。
假设有如下的对象
const employee = {
firstName: "Marko",
lastName: "Polo",
};
我们要获取值:
var firstName = employee.firstName;
当我们的对象有很多的属性和方法,用这种方法提取属性会很麻烦?
使用解构就非常的简单
{ firstName, lastName, position, yearHired } = employee;
我们还可以为属性取别名:
let { firstName: fName, lastName: lName, position, yearHired } = employee;
12.(ES6)有哪些新特性?
let const
模板字符串
解构
箭头函数
类
Promise
模块
Symbol
代理(proxy)
函数默认参数
13.函数声明与函数表达式的区别?
在Javscript中,解析器在执行代码的时候。
解析器会率先读取函数声明,
并【使其】在执行任何代码之前可用(可以访问)。
但是在执行函数表达式的时候,
则必须等到解析器执行到它所在的代码时,才会真正被解析执行。
14. 当一个DOM节点被点击时候,我们希望能够执行一个函数,应该怎么做?
<button onclick="xxx()"></button>
box.onlick= function(){}
box.addEventListener("click",function(){},false);
15 dom选择器优先级是什么,以及权重值计算(一道老问题了)
1.行内样式 1000
2.id 0100
3.类选择器、伪类选择器、属性选择器[type=“text”] 0010
4.标签选择器、伪元素选择器(::first-line) 0001
16. dom节点的根节点是不是body
不是,
dom节点的根节点是html
(包含head和body,head中分为meta、title等。body又分为一组)
17. 怎么判断两个对象相等
JSON.stringify(obj)==JSON.stringify(obj);//true
18.重绘和重排
重绘:当元素的一部分属性发生改变,
如背景、颜色等不会引起布局变化,
只需要浏览器根据元素的新属性重新绘制,
使元素呈现新的外观叫做重绘。
重排(回流):当render树中的一部分或者全部,
因为大小边距等问题,
发生改变而需要DOM树重新计算的过程
所以简单的来说就是。不会引起布局的变化,叫做重绘。
会引起布局的变化,叫做重排(回流)
所以在我们平时写css的时候,还是要按照html中类的顺序来写。
否者可能会造成重排,重排是需要消耗浏览器性能的哈。
19.引起重排的地方
1.添加、删除可见的dom
2.元素的位置改变
3.元素的尺寸改变(外边距、内边距、边框厚度、宽高)
4.页面渲染初始化
5.浏览器窗口大小改变
7.改变文字大小
10.操作class属性
11.内容的改变,(用户在输入框中写入内容也会)
20 请尽可能详尽的解释AJAX的工作原理。
1.创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp))
2.判断数据传输方式(GET/POST)
3.打开链接 open()
4.发送 send()
5.当ajax对象完成第四步(onreadystatechange)数据接收完成,判断http响应状态(status)200-300之间或者304(缓存)执行回调函数
21、ios滑动卡顿
-webkit-overflow-scrolling:touch 可能会在IOS系统低的情况出现滚动条;尝试溢出解决
、forEach和map的区别
相同点:
1.都是循环遍历数组中的每一项
2.forEach和map函数都支持3个参数,参数分别是item(当前每一项)、index(索引值)、arr(原数组)
3.匿名函数中的this都是指向window
4.只能遍历数组
都有兼容问题
不同点:
map速度比foreach快
map会返回一个新数组,不对原数组产生影响.foreach不会产生新数组,
map因为返回数组所以可以链式操作,foreach不能
get和post有什么区别?get可以通过body传递数据吗
把数据放到 body 里面,必须用 POST 方式取,这是 HTTP 协议限制的。
有趣的面试题
var User = {
count: 1,
getCount: function() {
return this.count;
}
};
console.log(User.getCount()); // what? 1
var func = User.getCount;
console.log(func()); // what? undefined
13.构造函数和实例对象和原型之间的关系 [想你画的那个图]
1.构造函数可以实例化对象
2.构造函数中有一个属性叫做prototype,是构造函数的原型对象。
{构造函数有两个箭头指向出去了的.}
3.构造函数的原型对象{prototype}中有一个constructor构造器,
这个构造器是指向[自己所在的原型对象]所在的[构造函数]。
4.构造函数的原型对象prototype中的方法可以被实例对象直接访问的。
5.实例对象的原型的对象(__proto__)指向的是该构造函数的原型对象。
1. 函数柯里化的实现,去了解一下这个东西是个什么玩意?
2.函数的深拷贝和浅拷贝是非常的复杂的。
3.什么是FOUC?你如何来避免FOUC?
https://juejin.cn/post/6844904200917221389#heading-63
什么是Proxy?
js 的几种模块规范?
有四种成熟模块加载方案:
第1种是 CommonJS 方案,它通过 require 来引入模块,通过 module.exports 定义模块的输出接口。
这种模块加载方案是服务器端的解决方案,它是以同步的方式来引入模块的.
因为在服务端文件都存储在本地磁盘,所以读取非常快.所以以同步的方式加载没有问题。
但如果是在浏览器端,由于模块的加载是使用网络请求,因此使用异步加载的方式更加合适。
第二种是 AMD 方案,这种方案采用异步加载的方式来加载模块.
模块的加载不影响后面语句的执行.
所有依赖这个模块的语句都定义在一个回调函数里.
等到加载完成后再执行回调函数。
require.js 实现了 AMD 规范。
第三种是 CMD 方案,这种方案和 AMD 方案都是为了解决异步模块加载的问题,
sea.js 实现了 CMD 规范。
它和require.js的区别在于:
模块定义时对依赖的处理不同和对依赖模块的执行时机的处理不同。
第四种方案是 ES6 提出的方案,使用 import 和 export 的形式来导入导出模块。
面试手写(原生):
//1:创建Ajax对象
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');// 兼容IE6及以下版本
//2:配置 Ajax请求地址
xhr.open('get','index.xml',true);
//3:发送请求
xhr.send(null); // 严谨写法
//4:监听请求,接受响应
xhr.onreadysatechange=function(){
if(xhr.readySate==4&&xhr.status==200 || xhr.status==304 ){
console.log(xhr.responsetXML)
}
}
参考的链接:
https://juejin.cn/post/6844904200917221389
https://blog.csdn.net/weixin_45151960/article/details/104832916