1、说说你对作用域链的理解
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的
简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。
2、JavaScript原型,原型链 ? 有什么特点?
每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时
如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。按照标准,__proto__ 是不对外公开的,也就是说是个私有属性
关系:instance.constructor.prototype == instance.__proto__
vara= {}
a.constructor.prototype==a.__proto__
特点:
JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变
当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的
就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象
原型:
JavaScript的所有对象中都包含了一个 [__proto__] 内部属性,这个属性所对应的就是该对象的原型
JavaScript的函数对象,除了原型 [__proto__] 之外,还预置了 prototype 属性
当函数对象作为构造函数创建实例时,该 prototype 属性值将被作为实例对象的原型 [__proto__]。
原型链:
当一个对象调用的属性/方法自身不存在时,就会去自己 [__proto__] 关联的前辈 prototype 对象上去找
如果没找到,就会去该 prototype 原型 [__proto__] 关联的前辈 prototype 去找。依次类推,直到找到属性/方法或 undefined 为止。从而形成了所谓的“原型链”
原型特点:
JavaScript对象是通过引用来传递的,当修改原型时,与之相关的对象也会继承这一改变
4、谈谈This对象的理解
this总是指向函数的直接调用者(而非间接调用者)
如果有new关键字,this指向new出来的那个对象
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window
5、new操作符具体干了什么呢?
创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型
属性和方法被加入到 this 引用的对象中
新创建的对象由 this 所引用,并且最后隐式的返回 this
6、Ajax原理
Ajax的原理简单来说是在用户和服务器之间加了—个中间层(AJAX引擎),通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据
Ajax的过程只涉及JavaScript、XMLHttpRequest和DOM。XMLHttpRequest是ajax的核心机制
/** 1. 创建连接 **/
varxhr=null;
xhr=newXMLHttpRequest()
/** 2. 连接服务器 **/
xhr.open('get', url, true)
/** 3. 发送请求 **/
xhr.send(null);
/** 4. 接受请求 **/
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
success(xhr.responseText);
} else {
/** false **/
fail&&fail(xhr.status);
}
}
}
ajax 有那些优缺点?
优点:
通过异步模式,提升了用户体验.
优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用.
Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
Ajax可以实现动态不刷新(局部刷新)
缺点:
安全问题 AJAX暴露了与服务器交互的细节。
对搜索引擎的支持比较弱。
不容易调试。
7、为什么要有同源限制?
同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议
举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。
8、javascript有哪些方法定义对象
对象字面量: var obj = {};
构造函数: var obj = new Object();
Object.create(): var obj = Object.create(Object.prototype);
9、说说你对promise的了解
依照 Promise/A+ 的定义,Promise 有四种状态:
pending: 初始状态, 非 fulfilled 或 rejected.
fulfilled: 成功的操作.
rejected: 失败的操作.
settled: Promise已被fulfilled或rejected,且不是pending
另外, fulfilled与 rejected一起合称 settled
Promise 对象用来进行延迟(deferred) 和异步(asynchronous) 计算
Promise 的构造函数
构造一个 Promise,最基本的用法如下:
varpromise=newPromise(function(resolve, reject) {
if (...) { // succeed
resolve(result);
} else { // fails
reject(Error(errMessage));
}
});
Promise 实例拥有 then 方法(具有 then 方法的对象,通常被称为thenable)。它的使用方法如下:
promise.then(onFulfilled, onRejected)
接收两个函数作为参数,一个在 fulfilled 的时候被调用,一个在rejected的时候被调用,接收参数就是 future,onFulfilled 对应resolve, onRejected对应 reject
vue、react、angular
Vue.js 一个用于创建 web 交互界面的库,是一个精简的 MVVM。它通过双向数据绑定把 View 层和 Model 层连接了起来。实际的 DOM 封装和输出格式都被抽象为了Directives 和 Filters
AngularJS 是一个比较完善的前端MVVM框架,包含模板,数据双向绑定,路由,模块化,服务,依赖注入等所有功能,模板功能强大丰富,自带了丰富的 Angular指令
react React 仅仅是 VIEW 层是facebook公司。推出的一个用于构建UI的一个库,能够实现服务器端的渲染。用了virtual dom,所以性能很好。
10、JS的基本数据类型和引用数据类型
基本数据类型:undefined、null、boolean、number、string、symbol
引用数据类型:object、array、function
11、介绍js有哪些内置对象
Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error
12、说几条写JavaScript的基本规范
不要在同一行声明多个变量
请使用===/!==来比较true/false或者数值
使用对象字面量替代new Array这种形式
不要使用全局函数
Switch语句必须带有default分支
If语句必须使用大括号
for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污
13、javascript创建对象的几种方式
javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON;但写法有很多种,也能混合使用
对象字面量的方式
person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};
用function来模拟无参的构造函数
functionPerson(){}
varperson=newPerson();//定义一个function,如果使用new"实例化",该function可以看作是一个Class
person.name="Mark";
person.age="25";
person.work=function(){
alert(person.name+" hello...");
}
person.work();
用function来模拟参构造函数来实现(用this关键字定义构造的上下文属性)
functionPet(name,age,hobby){
this.name=name;//this作用域:当前对象
this.age=age;
this.hobby=hobby;
this.eat=function(){
alert("我叫"+this.name+",我喜欢"+this.hobby+",是个程序员");
}
}
varmaidou=newPet("麦兜",25,"coding");//实例化、创建对象
maidou.eat();//调用eat方法
用工厂方式来创建(内置对象)
varwcDog=newObject();
wcDog.name="旺财";
wcDog.age=3;
wcDog.work=function(){
alert("我是"+wcDog.name+",汪汪汪......");
}
wcDog.work();
用原型方式来创建
functionDog(){}
Dog.prototype.name="旺财";
Dog.prototype.eat=function(){
alert(this.name+"是个吃货");
}
varwangcai=newDog();
wangcai.eat();
用混合方式来创建
functionCar(name,price){
this.name=name;
this.price=price;
}
Car.prototype.sell=function(){
alert("我是"+this.name+",我现在卖"+this.price+"万元");
}
varcamry=newCar("凯美瑞",27);
camry.sell();
14、null,undefined 的区别
undefined 表示不存在这个值。
undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。当尝试读取时会返回 undefined
例如变量被声明了,但没有赋值时,就等于undefined
null 表示一个对象被定义了,值为“空值”
null : 是一个对象(空对象, 没有任何属性和方法)
例如作为函数的参数,表示该函数的参数不是对象;
在验证null时,一定要使用 === ,因为 ==无法分别null 和 undefined
15、javascript 代码中的"use strict";是什么意思
use strict是一种ECMAscript 5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行,使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为
16、JSON 的了解
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小
JSON字符串转换为JSON对象:
varobj=eval('('+str+')');
varobj=str.parseJSON();
varobj=JSON.parse(str);
JSON对象转换为JSON字符串:
var last=obj.toJSONString();
var last=JSON.stringify(obj);
17、同步和异步的区别
同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作
异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容
18、谈谈你对ES6的理解
新增模板字符串(为JavaScript提供了简单的字符串插值功能)
箭头函数
for-of(用来遍历数据—例如数组中的值。)
arguments对象可被不定参数和默认参数完美代替。
ES6将promise对象纳入规范,提供了原生的Promise对象。
增加了let和const命令,用来声明变量。
增加了块级作用域。
let命令实际上就增加了块级作用域。
还有就是引入module模块的概念
19、ECMAScript6 怎么写class么
这个语法糖可以让有OOP基础的人更快上手js,至少是一个官方的实现了
但对熟悉js的人来说,这个东西没啥大影响;一个Object.creat()搞定继承,比class简洁清晰的多
20、什么是面向对象编程及面向过程编程,它们的异同和优缺点
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
面向对象是以功能来划分问题,而不是步骤
21、面向对象编程思想
基本思想是使用对象,类,继承,封装等基本概念来进行程序设计
优点
易维护
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的
易扩展
开发工作的重用性、继承性高,降低重复工作量。
缩短了开发周期
22、如何通过JS判断一个数组
instanceof方法
instanceof 运算符是用来测试一个对象是否在其原型链原型构造函数的属性
vararr= [];
arrinstanceofArray; // true
constructor方法
constructor属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数
vararr= [];
arr.constructor==Array; //true
最简单的方法
这种写法,是 jQuery 正在使用的
Object.prototype.toString.call(value) =='[object Array]'
// 利用这个方法,可以写一个返回数据类型的方法
varisType=function (obj) {
returnObject.prototype.toString.call(obj).slice(8,-1);
}
ES5新增方法isArray()
vara=newArray(123);
varb=newDate();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false
23、谈一谈let与var的区别
let命令不存在变量提升,如果在let前使用,会导致报错
如果块区中存在let和const命令,就会形成封闭作用域
不允许重复声明,因此,不能在函数内部重新声明参数
24、map与forEach的区别
forEach方法,是最基本的方法,就是遍历与循环,默认有3个传参:分别是遍历的数组内容item、数组索引index、和当前遍历数组Array
map方法,基本用法与forEach一致,但是不同的,它会返回一个新的数组,所以在callback需要有return值,如果没有,会返回undefined
25、谈一谈箭头函数与普通函数的区别?
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替
不可以使用yield命令,因此箭头函数不能用作Generator函数
26、JS 数组和对象的遍历方式,以及几种方式的比较
for in循环
for循环
forEach
这里的 forEach回调中两个参数分别为 value,index
forEach 无法遍历对象
IE不支持该方法;Firefox 和 chrome 支持
forEach 无法使用 break,continue 跳出循环,且使用 return 是跳过本次循环
这两种方法应该非常常见且使用很频繁。但实际上,这两种方法都存在性能问题
在方式一中,for-in需要分析出array的每个属性,这个操作性能开销很大。用在 key 已知的数组上是非常不划算的。所以尽量不要用for-in,除非你不清楚要处理哪些属性,例如 JSON对象这样的情况
在方式2中,循环每进行一次,就要检查一下数组长度。读取属性(数组长度)要比读局部变量慢,尤其是当 array 里存放的都是 DOM 元素,因为每次读取都会扫描一遍页面上的选择器相关元素,速度会大大降低
27、说一下Vue的双向绑定数据的原理
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
28、let var const
let
允许你声明一个作用域被限制在块级中的变量、语句或者表达式
let绑定不受变量提升的约束,这意味着let声明不会被提升到当前
该变量处于从块开始到初始化处理的“暂存死区”
var
声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的
由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明
const
声明创建一个值的只读引用 (即指针)
基本数据当值发生改变时,那么其对应的指针也将发生改变,故造成 const申明基本数据类型时
再将其值改变时,将会造成报错, 例如 const a = 3 ; a = 5时 将会报错
但是如果是复合类型时,如果只改变复合类型的其中某个Value项时, 将还是正常使用
29、JavaScript的组成
JavaScript由以下三部分组成:
ECMAScript(核心):JavaScript` 语言基础
DOM(文档对象模型):规定了访问HTML和XML的接口
BOM(浏览器对象模型):提供了浏览器窗口之间进行交互的对象和方法
30、介绍JS有哪些内置对象
数据封装类对象:Object、Array、Boolean、Number、String
其他对象:Function、Arguments、Math、Date、RegExp、Error
ES6新增对象:Symbol、Map、Set、Promises、Proxy、Reflect
31、说几条写JavaScript的基本规范
代码缩进,建议使用“四个空格”缩进
代码段使用花括号{}包裹
语句结束使用分号;
变量和函数在使用前进行声明
以大写字母开头命名构造函数,全大写命名常量
规范定义JSON对象,补全双引号
用{}和[]声明对象和数组
32、解释JavaScript中的作用域与变量声明提升
JavaScript作用域:
在Java、C等语言中,作用域为for语句、if语句或{}内的一块区域,称为作用域;
而在 JavaScript 中,作用域为function(){}内的区域,称为函数作用域。
JavaScript变量声明提升:
在JavaScript中,函数声明与变量声明经常被JavaScript引擎隐式地提升到当前作用域的顶部。
声明语句中的赋值部分并不会被提升,只有名称被提升
函数声明的优先级高于变量,如果变量名跟函数名相同且未赋值,则函数声明会覆盖变量声明
如果函数有多个同名参数,那么最后一个参数(即使没有定义)会覆盖前面的同名参数
33、列举一下JavaScript数组和对象有哪些原生方法?
数组:
arr.concat(arr1, arr2, arrn);
arr.join(",");
arr.sort(func);
arr.pop();
arr.push(e1, e2, en);
arr.shift();
unshift(e1, e2, en);
arr.reverse();
arr.slice(start, end);
arr.splice(index, count, e1, e2, en);
arr.indexOf(el);
arr.includes(el); // ES6
对象:
object.hasOwnProperty(prop);
object.propertyIsEnumerable(prop);
object.valueOf();
object.toString();
object.toLocaleString();
Class.prototype.isPropertyOf(object);
34、Array.slice() 与 Array.splice() 的区别?
slice
“读取”数组指定的元素,不会对原数组进行修改
语法:arr.slice(start, end)
start 指定选取开始位置(含)
end 指定选取结束位置(不含)
splice
“操作”数组指定的元素,会修改原数组,返回被删除的元素
语法:arr.splice(index, count, [insert Elements])
index 是操作的起始位置
count = 0 插入元素,count > 0 删除元素
[insert Elements] 向数组新插入的元素
35、MVVM
MVVM 由以下三个内容组成
View:界面
Model:数据模型
ViewModel:作为桥梁负责沟通 View 和 Model
36、this指向
1、this 指向有哪几种
默认绑定:全局环境中,this默认绑定到window
隐式绑定:一般地,被直接对象所包含的函数调用时,也称为方法调用,this隐式绑定到该直接对象
隐式丢失:隐式丢失是指被隐式绑定的函数丢失绑定对象,从而默认绑定到window。显式绑定:通过call()、apply()、bind()方法把对象绑定到this上,叫做显式绑定
new绑定:如果函数或者方法调用之前带有关键字new,它就构成构造函数调用。对于this绑定来说,称为new绑定
构造函数通常不使用return关键字,它们通常初始化新对象,当构造函数的函数体执行完毕时,它会显式返回。在这种情况下,构造函数调用表达式的计算结果就是这个新对象的值
如果构造函数使用return语句但没有指定返回值,或者返回一个原始值,那么这时将忽略返回值,同时使用这个新对象作为调用结果
如果构造函数显式地使用return语句返回一个对象,那么调用表达式的值就是这个对象
2. 改变函数内部 this 指针的指向函数(bind,apply,call的区别)
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法
bind除了返回是函数以外,它的参数和call一样
3. 箭头函数
箭头函数没有this,所以需要通过查找作用域链来确定this的值,这就意味着如果箭头函数被非箭头函数包含,this绑定的就是最近一层非箭头函数的this,
箭头函数没有自己的arguments对象,但是可以访问外围函数的arguments对象
不能通过new关键字调用,同样也没有new.target值和原型