1.js的的数据类型有哪些?分别是?
基本数据类型、引用类型、特殊类型
基本数据类型:String、Number、Boolean、undefined、unll (新增Symbol)
引用类型 : function、Object
特殊类型 :undefined、null
2.原型链是什么 ?
用new运算符加上函数的调用,调用的结果就是一个对象,new出来的这个对象我们称他为实例
prototype(原型)是一个指针指向了一个原型对象,这个对象里面存放所有的实例共享的属性和方法
实例的__proto__指向了构造函数的prototype,构造函数是object的实例,构造函数的prototype下的__proto__指向了object的prototype 我们称他为原型链
3.javascript作用链域?
全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。
当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找,
直至全局函数,这种组织形式就是作用域链。
4.谈谈This对象的理解。
- 全局this指window
- 事件对象里面的this指事件触发对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window
- 自调用函数this指window
- 对象方法里面的this指对象本身
- 构造函数的this及构造函数原型方法里面的this都是指向将来new的实例对象
- 没有归属的局部函数this指向window
- 箭头函数没有自己的this
- forEach,reduce,定时器里面的this都是指向window
5.改变this指向的方法
bind方法:在函数声明的时候改变this的指向
call方法:是在函数调用的时候改变this的指向(window,18,19,20)传参的方式不一样
apply方法: 是在函数调用的时候改变this的指向(window,[18,19,20])传一个数组
6.什么是闭包(closure),为什么要用它?
- 函数内再嵌套函数
- 内部函数可以引用外层的参数和变量
- 参数和变量不会被垃圾回收机制回收
7.new操作符具体干了什么呢?
- 创建一个空对象
- 将创建的对象的_proto_指向构造函数的prototype
- 改变了this的指向
- 返回了一个对象
function create(Con,...args) {
const obj = {}
obj._proto_ = Con.prototype
coonst result = Con.apply(obj,args)
return result instanceof object ? result : obj
}
8.Ajax 是什么? 如何创建一个Ajax?
异步传输+js+xml
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象
(2)使用 XMLHttpRequest对象的open()和send()方法发送资源请求给服务器
(3)onreadystatechange函数,状态改变时发送数据回客户端,使用 XMLHttpRequest对象的responseText 或responseXML属性获得服务器的响应
//GET方法
var xhr= new XMLHttpRequest();
xhr.open("GET","url",true); //get请求,url请求地址,true代表异步
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
}
//POST方法
var ajax = new XMLHttpRequest();
ajax.open("POST","url",true);
ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajax.send("name=zhangsan&age=18");
ajax.onreadystatechange = function(){
if(ajax.readyState == 4){
if (ajax.status == 200) {
var json = JSON.parse(ajax.responseText);
fn(json);
}
9.常见的跨域方式有几种
jsonp、cors、代理服务器
<button onclick="sendMsg()">发送请求</button>
<script>
function fn(resp) {
console.log(resp)
}
function sendMsg() {
tools.jsonp('http://localhost/day24-ajax-promise/02.php', 'fn', { id: 10 })
}
/** jsonp跨域请求
* @param url <string> 请求地址
* @param cb <string> 回调函数名
* @param query <object> 要携带的其他参数
*/
jsonp: function (url, cb, query) {
url += `?cb=${cb}`
if (query) {
for (var key in query) {
url += `&${key}=${query[key]}`
}
}
// 创建script标签
var script = document.createElement('script')
script.src = url
document.body.appendChild(script)
document.body.removeChild(script) // 过河拆桥
}
10.AMD、CMD规范区别?
区别:
- 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
- AMD 推崇依赖前置,CMD 推崇依赖就近。
- AMD提前执行(不管什么时候使用,首先加载在代码的头部)//特点:前期网络资源消耗大,后期平稳 代表作 require.js
- CMD按需执行: //特点:网络资源的消耗处于平缓的状态,随时都有可能在加载模块 代表作 sea.js
// AMD 默认推荐
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
// ...
})
//引入模块
//按顺序引入的模块,在回调函数里面也可以按顺序接受
require(['要使用的模块路径/文件名不加后缀'],( 接受模块的返回 class类) =>{
new 接受模块的返回class类
})
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ...
})