1、怎么删除数组指定下标的值?怎么在数组指定下标后插入值?怎么在数组中替换指定下标的值?
let a = [1,2,3,4,5]; a.slice(-1)[0];
a.splice(2,1); // 从下标2开始,删除1个数 。效果:3被删除
a.splice(2,0,‘6’); // 从下标2开始,删除0个数,插入一个字符‘6’。效果:3替换成‘6’
a.splice(2,1,‘red’,‘blue’); // 从下标2开始,删除1个数,插入字符‘red’和‘blue’。效果:3替换成了’red’,‘blue’
2、什么是生成器(generator)?有什么用?
function *fn() {};
or
let fn = function* (); // 箭头函数不能用来声明生成器
生成器实现迭代接口,所以有next()方法,生成器开始是暂停状态即不会执行方法内逻辑,.next()后才执行,返回一个对象,有两个属性:done和value。分别表示生成器状态(返回true或false)和生成器(如上的fn)的return返回的值。
function* fn() {
console.log('0');
yield '第一次执行next的返回{done: false, 1}';
console.log('1');
yield '第二次执行next的返回{done: false, 2}';
console.log('2');
return '第三次执行next的返回{done: true, 3}';
console.log('3');
};
let test = fn();
let test2 = fn();
test.next();
test.next();
test2.next();
// 0
// 1
// 0
// {value: '第一次执行next的返回{done: false, 1}', done: false}
// ----------其它---------
// 循环示例如下,现象:类似连续调用next到done为true;
for (item of test) {
console.log('生成器循环');
console.log(item);
}
生成器的主要作用是可以使用yield 来中断逻辑,经过交互再使用next继续逻辑。
生成器内部会区分作用域,生成器对象不会相互影响。
使用场景:例如避免回调地狱等
3、
对象有属性,属性分数据属性和访问器属性,属性有各自的特性,比如[[Writable]],[[Get]],[[Set]],这些特性不能直接访问,但可以通过哪个方法来间接修改?
Object.defineProperty() // 第一个参数:给其添加属性的对象,第二个:属性名称,第三个:描述符对象
// 如:
let book = {
currentYear: 2017,
edit: 1,
};
Object.defineProperty(book, 'year', {
get() {
return '现在是' + this.currentYear;
},
set(newValue) {
if (newValue > 2017) {
this.currentYear = newValue;
this.edit += (newValue - 2017)
} else {
this.currentYear = 2017;
}
}
})
book.year = 2018;
console.log(book.edit) // 2
console.log(book.currentYear) // 2018
console.log(book.year) // 现在是2018
book.year = 2016;
console.log(book.year) // 现在是2017
4、什么是代理?js怎么创建代理?
// 最简单的定义
let target = {
id: '1',
};
let handler = {};
let proxy = new Proxy(target, handler) // 第一个参数是目标对象;第二个参数是处理程序对象,是代理嵌入的额外操作
// 复杂一些,给处理程序对象内添加各种破获器
let handler = {
get(trapTarget, property, receiver) { // 这是get捕获器。参数:目标对象,要查询的属性,代理对象
return property + ':这是get捕获器内的返回'; // 换成trapTarget[property]即打印返回:1:这是get捕获器内的返回
}
};
console.log(proxy.id)) // id:这是get捕获器内的返回
5、 什么是纯函数?(如redux的 reducer就需要上纯函数)
const initialState = { value: 0 }
function counterReducer(state = initialState, action) {
// 检查 reducer 是否关心这个 action
if (action.type === 'counter/increment') {
// 如果是,复制 `state`
return {
...state,
// 使用新值更新 state 副本
value: state.value + 1
}
}
// 返回原来的 state 不变
return state
}
6、纯函数的好处?
var memoize = function(f) {
var cache = {};
return function() {
var arg_str = JSON.stringify(arguments);
cache[arg_str] = cache[arg_str] || f.apply(f, arguments);
return cache[arg_str];
}; };
var squareNumber = memoize(function(x){ return x*x; });
squareNumber(4);
//=> 16
squareNumber(4);
//=> 16
squareNumber(5);
//=> 25
squareNumber(5);
//=> 25
纯函数总能够根据输入来做缓存。实现缓存的一种典型方式是 memoize 技术
Tip: 函数如果有引用外部的的变量,为了纯函数化,需要处理这个变量,讲变量设定为不可变。如下对象,不可新增删除修改属性
var immutableState = Object.freeze({
minimum: 21
});
7、什么叫 副作用?
- 改变/修改输入参数,如:入参是一个对象,方法内为这个对象新增一个属性,再返回这个对象
- 修改函数外的任何其他状态,如全局变量,document.(anything)或window.(anything)
- 进行 API 调用 如:fetch('/users')
- console.log()
- Math.random()
8、js哪些方法会修改原数组?React里的概念,即是可变的(mutability)
push(在末尾添加一个项目)
pop(从末尾删除一个项目)
shift (从头删除一个项目)
unshift(在开头添加一个项目)
sort(排序-可自定义比较规则)
reverse 逆序
splice 处理原数组(删除,替换)