面试题

1、Object有哪些方法?
Object.assign():通过复制一个或多个对象来创建一个新的对象
Object.create():使用指定的原型对象和属性创建一个新对象
Object.keys():返回一个包含所有给定对象自身可枚举属性名称的数组
Object.getOwnPropertyNames():返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名
Object.values():返回给定对象自身可枚举值的数组
Object.entries():返回给定对象自身可枚举属性的 [key, value] 数组
demo: for(let [key, value] of Object.entries(object1))
Object.is():比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)
Object.freeze():冻结对象:其他代码不能删除或更改任何属性
Object.defineProperties(): 给对象添加多个属性并分别指定它们的配置

1
2
3
4
5
6
7
8
9
10
11
12
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.
});

Object.defineProperty(): 给对象添加一个属性并指定该属性的配置

1
2
3
4
5
6
7
8
var obj = {};
// 显式
Object.defineProperty(obj, "key", {
enumerable: false,
configurable: false,
writable: false,
value: "static"
});

2、对象的属性描述符:数据描述符和存取描述符
数据描述符:configurable、enumerable、value、writable
存取描述符:configurable、enumerable、get、set(默认undefined)
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
3、for…in与for…of的区别
for in是ES5标准,遍历key.适用于对象
for in遍历对象存在的问题:
for in 可以遍历到原型上的方法和属性,hasOwnPropery方法可以判断某属性是否是该对象的实例属性
for in遍历数组存在的问题:
1.index索引为字符串型数字,不能直接进行几何运算
2.遍历顺序有可能不是按照实际数组的内部顺序
3.使用for in会遍历数组所有的可枚举属性(包括length),包括原型
for of是ES6标准,遍历value。适用于数组
for…of用于对象会报错,’obj’ is not iterable不是一个 可迭代对象.
在JavaScript中, Object 是不可迭代的,除非它们实现了迭代协议. 因此, 你不能使用 for…of 来迭代对象的属性.
一个可迭代对象可以是一个内置可迭代类型,如Array, String 或 Map,
4、arr.find()与arr.filter()的区别,以及都没有匹配上时返回什么?
find()函数用来查找目标元素,找到就返回该元素,找不到返回undefined。返回的是对象,如遇到重复的值只会返回第一次出现的值
filter过滤 返回全部结果仍然是数组。如果没有任何数组元素通过测试,则返回空数组
5、es6中的Reflect和proxy:Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API
Reflect对象的设计目的:

  1. 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。
  2. 修改某些Object方法的返回结果,让其变得更合理
  3. 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
    Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
    Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
    Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与处理器对象的方法相同。
    处理器对象(handler)用来自定义代理对象(Proxy)的各种可代理操作。
    Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)
    1
    2
    3
    //target:用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
    //handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数。
    let p = new Proxy(target, handler);

Reflect不是一个函数对象,因此它是不可构造的。
Reflect的所有属性和方法都是静态的(就像Math对象)。
6、Object.defineProperty()的作用:创建属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Object.defineProperty(obj, "key", {
enumerable: false,
configurable: false,
writable: false,
value: "static"
});

Object.defineProperty(o, "b", {
get : function(){
return bValue;
},
set : function(newValue){
bValue = newValue;
},
enumerable : true,
configurable : true
});

7、笔试题:ajax的缺点,共享数据,cookie
ajax的缺点:
1.AJAX干掉了Back和History功能,即对浏览器机制的破坏:在动态更新页面的情况下,用户无法回到前一个页面状态
2.AJAX的安全问题:会暴露比以前更多的数据和服务器逻辑
3.对搜索引擎支持较弱
4.破坏程序的异常处理机制,给我们的调试带来了很大的困难
5.AJAX不能很好支持移动设备
6.客户端过肥,太多客户端代码造成开发上的成本
session共享问题:
项目使用nginx做负载均衡,这样同一个IP访问同一个页面会被分配到不同的服务器上,此时就涉及到一个session共享的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就会丢失,一般情况下,session不可跨服务器而存在。于是就有了分布式系统的session共享问题。