1.javascript如何判断变量为对象?

  1. var obj = {}
  2. //第一种(注意,"[object Object]"第一个O为小写,第二个为大写)
  3. Object.prototype.toString().call(obj) === "[object Object]" // true
  4. //第二种
  5. obj.constructor === Object //true
  6. //第三种
  7. obj instanceof Object // true
  8. //注:需要注意的是由于数组也是对象,因此用 arr instanceof Object 也为true。

2.JavaScript中foreach与map的区别?
forEach()方法不会返回执行结果,而是undefined。也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回。
forEach()的执行速度比map()慢了 70%。每个人的浏览器的执行结果会不一样。

3. var、let、const区别

使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值;
如果const声明的是一个对象,那么是可以更改这个对象的值,原因是const是根据内存指针指向栈内存,更改对象的值并不会更改指针,所以对象的值是可以更改的。如果要使一个对象无法添加新属性,不能修改其已有属性的值,不能删除已有属性,使用

  1. object.freeze(obj)
  2. //参数:obj要冻结的对象
  3. //返回值:被冻结的对象
  4. //冻结对象的所有自身属性都不可能以任何方式被修改。
  5. //数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。
  6. //如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。

4.vue和react中key的用途?实际应用的场景?

  1. 更准确
    因为带key就不是就地复用了,在sameNode函数 a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。
  2. 更快
    利用key的唯一性生成map对象来获取对应节点,比遍历方式更快

更准确因为带key就不是就地复用了,在sameNode函数 a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。更快利用key的唯一性生成map对象来获取对应节点,比遍历方式更快虚拟dom到真实dom的隐射并反映,dom节点的比较需要用到diff算法

v-for与map遍历dom元素必须绑定卫一的key,操作key可以强制刷新视图

5.介绍盒模型

5.1 W3C标准盒模型:
属性width和height只包括content,不包含border和padding
5.2 IE盒模型:
属性width和height包括border和padding,指的是content+padding+border

在ie8+浏览器中使用哪个盒模型可以由box-sizing(CSS新增的属性)控制,默认值为content-box,即标准盒模型;如果将box-sizing设为border-box则用的是IE盒模型。如果在ie6,7,8中DOCTYPE缺失会触发IE模式。在当前W3C标准中盒模型是可以通过box-sizing自由的进行切换的。

6.CSS定位详解

position属性有五个值:
static:默认值,不设置position属性时,默认为static定位
relative:相对于static定位,即相对于默认位置定位
absolute:相对于父级元素定位,并且父级元素不能是static定位,否则定位基点为根元素HTML
fixed:相对浏览器窗口定位,这回导致元素不跟随页面滚动而变化
sticky:会产生动态效果,有时是relative定位,有事是fixed定位
sticky详解:当页面滚动,父元素开始脱离视口(即部分不可见),只要与sticky元素的距离达到生效门槛,relative定位自动转换成fixed定位;等到父元素完全脱离视口(即完全不可见)fixed定位自动切换会relative定位

7.javascript作用域

7.1 全局作用域
生命周期将存在于整个程序之内,能被程序中的任何函数或者方法访问,在JavaScript内默认是可以修改的
不带有声明关键字的变量,默认为全局变量
函数不经过封装,也会是全局变量
7.2 函数作用域
函数作用域内,对外是封闭的,外层作用域无法直接访问函数作用域,但是可以通过函数的return访问函数的内部变量
立即执行函数可以很好的分离全局作用域,形成一个单独的函数作用域
7.3 块级作用域

  1. for(var i = 0; i < 5; i++) {
  2. // ...
  3. }
  4. console.log(i) // 5

用var声明的变量当for循环结束后仍然保存在这个作用域里面,这可以说明for() { }仍然在全局作用域里,并没有产生像函数一样的封闭效果;想要实现块级作用域需要使用let关键字声明

  1. for(let i = 0; i < 5; i++) {
  2. // ...
  3. }
  4. console.log(i) // 报错:ReferenceError: i is not defined

在for循环执行完毕后I变量就被释放了,同时可以形成块级作用域的还有const关键字,创建块级作用域的条件必须有一个 { } 包裹
7.4 词法作用域
总结来说就是就近原则
7.5 动态作用域
就近原则,除了this之外,其他都是根据词法作用域查找

8. vue双向绑定原理

  1. 通过数据劫持结合发布者-订阅者模式的方式实现。<br />数据劫持:<br />Object.defineProperty(要定义属性的对象, 要定义或修改的属性的名称或 [`Symbol`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol), 要定义或修改的属性描述符)<br />通过Object.defineProperty设置属性时,对其set和get进行重写操作,get就是在读取这个属性,set就是在设置这个属性是触发的函数<br />监听器:<br />Observer用来劫持并监听所有属性,如果有变动就通知订阅者<br />要对所有属性进行监听,就要递归遍历所有的属性,并对其进行Object.defineProperty处理
  1. function defineReactive(data, key, val) {
  2. observe(val); // 递归遍历所有子属性
  3. Object.defineProperty(data, key, {
  4. enumerable: true,
  5. configurable: true,
  6. get: function() {
  7. return val;
  8. },
  9. set: function(newVal) {
  10. val = newVal;
  11. console.log('属性' + key + '已经被监听了,现在值为:“' + newVal.toString() + '”');
  12. }
  13. });
  14. }

订阅者:
Watcher可以收到属性变化的通知并执行相应的函数,从而更新视图
解析器:
Compile扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器

9.什么是跨域?解决方案?怎么实现?

什么是跨域?
在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制
同源策略是一种约定,如果少了同源策略,浏览器很容易收到XSS、CSFR攻击,
所谓同源是指协议+域名+端口三这个相同,即便两个不通的域名指向同一个ip地址,也非同源

解决方案:

  1. 1. jsonp跨域

jsonp的原理就是利用script标签没有跨域限制,通过src属性发送带有Callback参数的get请求。
后端返回参数是执行这个callback;jsonp稚嫩恶搞发送get一种请求

  1. 1. postMessage跨域
  2. 1. HTML5 XMLHttpRequest Level 2中的api postMessagedataorigin)方法接受两个参数
  3. 1. data:html5规范支持任意基本类型或可复制的对象,但部分浏览器支支持字符串,所以传参时尽量用使用JSON.stringify()序列化
  4. 1. origin 协议+主机+端口号,也可以设置为*,表示可以传递给任意窗口,如果要置顶和当前窗口同源的话设置为‘/’

10.阻止事件冒泡和事件捕获?

阻止事件冒泡

  1. document.getElementById("button").addEventListener("click",function(event){
  2. alert("button");
  3. event.stopPropagation();
  4. },false);

event.stopPropagation(); 停止冒泡事件的传播
阻止事件的捕获

  1. document.getElementById("second").addEventListener("click",function(){
  2. alert("second");
  3. event.stopImmediatePropagation();
  4. },true);

event.stopImmediatePropagation

11.虚拟DOM与真实DOM那个速度更快?

使用虚拟dom计算:
总损耗 = 虚拟DOM增删改 + (与Diff算法效率有关)真实DOM增删改 + (较少的节点) 排版与重绘
使用真是DOM损耗计算:
总损耗 = 真实的DOM完全增删改 + (可能较多的节点)排版与重绘

12.vueX相关

  1. 5个核心属性是什么?
    1. state
    2. getters
    3. mutations
    4. actions
    5. modules
  2. Vuex状态存储在哪里怎么改变他?
    1. 存储在state中,改变Vuex中的状态唯一途径就是提交(commit)mutations。
  3. Vuex中状态是对象时,使用需要注意什么?
    1. 因为对象是引用数据类型,复制后改变属性还是会影响原始数据,这样会改变state里面的状态,是不允许的,所以线深度克隆对象,在进行修改
  4. Vuex中要冲state中派生出一些状态出来,且多个组件使用它,该怎么做?
    1. 使用getter属性,相当于computed只有原状态改变派生状态才改变,getter接受两个参数,第一个是state第二个是getters,可以访问其他getter
    2. 然后再组件中可以使用computed通过this.$store.getters.函数名来访问这些派生状态