js 面试题搜罗, 一些代码段
js 面试题搜罗
ES6
///////////////////////////////
// from page-82
// try-p82-keys
var obj ={
a:1,
b:2,
};
Object.setPrototypeOf(obj,{
c:3,
});
console.log(Object.keys(obj)); // ["a", "b"]
console.log(JSON.stringify(obj)); // {"a":1,"b":2}
var keys1 =[];
for(let key in obj)keys1.push(key);
console.log(keys1); // ["a", "b", "c"]
var keys2 =[];
for(let key in Object.assign({},obj))keys2.push(key);
console.log(keys2); // ["a", "b"]
///////////////////////////////
逻辑
///////////////////////////////
// 逻辑 a=1 b=2 不使用第三个变了量交换a,b
// var a = 1, b = 2;
// // 最牛逼的
// a = [b,b=a][0]
// 0使用临时变量 - low
// var t = a
// a = b
// b = t
// 1
// a = a + b
// b = a - b
// a = a - b
// 2-1
// a = a^b //a^=b
// b = b^a //b^=a
// a = a^b //a^=b
// 2-2
// a = (b^=a^=b)^a;
// 3
// a = {a: b,b: a}
// b = a.b
// a = a.a
// 4
// a = [a,b]
// b = a[0]
// a = a[1]
// 5 ES6 解构赋值
// [a,b] = [b,a]
// console.log('ab值互换', a, b)
///////////////////////////////
变量提升
///////////////////////////////
// 变量提升 函数优先级高于变量
function blts(){
console.log(a);// undefined
var a = 2;
}
blts();
function fn(a){
console.log(a); // a(){}
var a = 2;
function a(){}
console.log(a); // 2
}
fn(1)
var time = function(){
console.log(1);
return 1
}
function time(){
console.log(2)
return 2
}
console.log('构造函数: ', time()); // var time 1; => 构造函数: 1
///////////////////////////////
///////////////////////////////
// 变量提升 + 原型链
function Foo(){
getName = function(){ console.log(1) }
return this
}
Foo.getName = function(){ console.log(2) }
Foo.prototype.getName = function(){ console.log(3) }
var getName = function(){ console.log(4) }
function getName(){ console.log(5) }
// 请写出以下输出结果
Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); //3
///////////////////////////////
///////////////////////////////
//
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x); // undefined
console.log(b.x); // {n: 2}
///////////////////////////////
///////////////////////////////
//
function test(person) {
person.age = 26
person = {
name: 'yyy',
age: 30
}
return person
}
var p1 = {
name: 'yck',
age: 25
}
const p2 = test(p1)
console.log(p1) // {age: 26, name: "yck"}
console.log(p2) // {age: 30, name: 'yyy'}
///////////////////////////////
///////////////////////////////
//
var foo = {
bar: function(){
let barr = 'barr'
console.log(barr, this.barr)
return this.baz;
},
baz: 1
};
(function(){
arguments.barr = 'arguments-barr'
arguments.baz = 'arguments-baz'
// console.log(this) // window
// console.log(arguments) // Arguments {}
console.log(arguments[0]) // 匿名函数: f(){let barr...}
console.log(typeof arguments[0]()); // undefined
})(foo.bar)
// 这里 this 指向 arguments , arguments 调用的
///////////////////////////////
///////////////////////////////
//
console.log( '{} + [] //', {} + []); // [object Object]
console.log( '[] + {} //', [] + {}); // [object Object]
console.log( '{} + [] == 0', {} + [] == 0 ); // false
console.log( '{a:1} + [] == 0', {a:'1'} + [] == 0 ); // false
console.log( '[] + {} == 0', [] + {} == 0 ); // false
///////////////////////////////
///////////////////////////////
// 1
console.log(a);
var a = 12;
function fn(){
console.log(a);
var a = 13;
}
fn();
console.log(a);
// undefined undefined 12
///////////////////////////////
// 2
console.log(a);
var a = 12;
function fn(){
console.log(a);
a = 13;
}
fn();
console.log(a);
// undefined 12 13
// 3
console.log(a);
a = 12;
function fn(){
console.log(a);
a = 13;
}
fn();
console.log(a);
// 报错 a is not defined
// 4
/**
* 变量提升
* var foo;
* bar = aaafff000;
*/
var foo = 1;
function bar(){
/**
* 形参赋值: 无
* 变量提升
* var foo; (不管条件是否成立, 都要进行变量提升, 新浏览器中对于判断体中的函数只是提前声明)
*/
if(!foo){ // => !undefined => true
var foo = 10;
}
console.log(foo); // => 10
}
bar(); // 10
// 5 变量/函数 声明提升, 闭包 保存/保护 作用
var n = 0;
function a(){
var n = 10;
function b(){
n++;
console.log(n); // => 11
}
b();// => 12
return b;
}
var c = a();
c();
console.log(n); // => 0
// 6
var a = 10, b = 11, c = 12;
function test(a){
a = 1;
var b = 2;
c = 3;
}
test(10);
console.log(a) // 10
console.log(b) // 11
console.log(c) // 3
// 7 不管条件是否成立, 都要进行变量提升
if(!('a' in window)) {
var a = 1;
}
console.log(a); // undefined
// 8 arguments 累数组对象{x, y, a}
// 变量提升
// var a;
// b = aaafff000;
var a = 4;
function b(x, y, a) {
// 形参赋值: x=1 y=2 a=3
// 变量提升
//=> arguments: 函数内置的实参集合, 不管是否设置形参,传递的实参值在这个集合都存在
// arguments: {0: 1, 1: 2, 2: 3, length: 3, callee: 函数本身b(){}...}
// 在js非严格模式下, 函数中的形参变量和arguments存在映射机制(映射: 相互之间影响)
// 第一个形参变量值修改为100,那么ARG[0]的值也跟着修改为100;
// ARG[1]的值修改为200, 那么第二个形参变量Y的值也会跟着变为200...
console.log(a); // 3
arguments[2] = 10; //=>把传递的第三个实参值修改为10, 此时第三个形参变量a也会受到影响
console.log(a); // 10
}
a = b(1,2,3);
console.log(a); // undefined
// 8-1 arguments 形参 映射机制(非严格模式)
function fn(x,y) {
// 形参
// x = 10
// y = undefined
// ARG
// 0: 10
// length: 1
/// ARG和形参之间的映射是以ARG的索引为基础完成的,
/// ARG中有这个索引, 浏览器会完成对应形参变量中的映射机制搭建,
/// 如果形参比ARG中个数多, 那么多出的形参是无法和ARG中对应的索引建立关联的
var arg = arguments;
arg[0] = 100;
console.log(x); // 100
y = 200;
console.log(arg[1]); // undefined
arg[1] = 300;
console.log(y); // 200
//=> arguments和形参的映射机制建立函数执行后形参赋值的一瞬间, 此时能建立映射机制的建立映射机制, 不能建立起来的, 以后不管怎么操作都无法建立了
}
fn(10);
// 8-2 JS 严格模式
// => 在当前作用域的第一行 添加 'use strict' 即可, 这样在当前作用域中就开启了js的严格模式
/*-- use [TAB] --*/
//'use strict'; //=> 整个js都开启了严格模式(只对当前文件的代码生效, 下一个JS文件需要开启严格模式, 第一行还需要在编写)
// 真实项目中, 把所有 JS 文件合并压缩为一个导入到页面中
// 故使用闭包 防止严格模式失效
~function(){
'use strict';
// ...自己的代码
}();
~function(){
// ...别人的代码
}();
// 8-3 JS 严格模式和非严格模式 区别
//=> 1. 严格模式下 arguments.callee/ arguments.callee.caller 不能使用(报错 在严格模式下不能使用)
//=> 2. 在严格模式下 ARGUMENTS和形参没有映射机制
//=> 3. 在严格模式下不允许给一个对象设置重复属性名的: "obj={n:1,n:2}"
//=> 4. 在严格模式下, 函数执行, 如果没有明确指定执行的主体(函数前面没有点.), 不再像非严格模式下一样, 都统一交给window, 而是让this 指向undefined, 代表没有执行主体
function fn(){console.log(this)} fn(); // window(非严格模式) undefined(严格模式)
// =>高程三, 最后有严格模式和非严格模式汇总
var color = 'red';
delete color; //严格模式不允许对变量调用delete操作符; 非严格模式可以, 但是会静默失败(返回false);严格模式下删除变量也会导致错误.
console.log(color)
///////////////////////////////
///////////////////////////////
//费波拉希数列
function fib(n) {
return function(n, a, b) {
return n > 0 ? arguments.callee(n - 1, b, a + b) : a;
} (n, 0, 1);
}
// console.log(fib(0)); //0
// console.log(fib(1)); //1
// console.log(fib(2)); //1
// console.log(fib(3)); //2
// console.log(fib(4)); //3
// ......
// console.log(fib(50)); //12586269025
// console.log(fib(51)); //20365011074,这里是上到第50个阶梯
let fibn = fib(10);
console.log(fibn); // 55
function generateFibonaccis(n){
var fib = [1, 1]
for( var i = 2; i < n; i++){
fib[i] = fib[i-2] + fib[i-1]
}
return fib
}
let fibonaccis = generateFibonaccis(10);
console.log(fibonaccis.join(' ')); // 1 1 2 3 5 8 13 21 34 55
///////////////////////////////
Array 数组
///////////////////////////////
/** 第 30 题:数组合并: 请把俩个数组
* [A1, A2, B1, B2, C1, C2, D1, D2] 和 [A, B, C, D],
* 合并为 [A1, A2, A, B1, B2, B, C1, C2, C, D1, D2, D]
*/
let arr1 = ['A1','A2','B1','B2','C1','C2','D1','D2']
let arr2 = ['A','B','C','C'].map( item =>{
return item + 3
})
let arr3 = [...arr1, ...arr2] .sort().map((item) => {
if(item.includes('3')){
return item.split('')[0]
}
return item
})
console.log(arr3); // ["A1", "A2", "A", "B1", "B2", "B", "C1", "C2", "C", "C", "D1", "D2"]
///////////////////////////////
///////////////////////////////
/** 数组给定一个整数数组 nums 和一个目标值 target,
* 请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
* 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
*
* 示例:
* 给定 nums = [2, 7, 11, 15], target = 9
* 因为 nums[0] + nums[1] = 2 + 7 = 9
* 所以返回 [0, 1]
*/
var twoSum = function (nums, target) {
const map = {};
const len = nums.length;
for (let i = 0; i < len; i++) {
const res = target - nums[i];
if (map[res] || map[res] === 0) {
return [map[res], i]
}
map[nums[i]] = i;
}
};
console.log(twoSum([4,1,3,2],3)) // [1, 3]
///////////////////////////////
ES6
///////////////////////////////
// const
var CONST = {};
Object.defineProperty(CONST, 'a', {
value: 2,
writable: false,
configurable: false,
enumerable: true,//可枚举
})
console.log('CONST.a = ', CONST.a);
CONST.a = 3;
console.log('改变了没? CONST.a = ',CONST.a); // 2 相当于ES6的const 定义的常量不可改变
///////////////////////////////
///////////////////////////////
// a == 1 && a == 2 && a == 3 值为 true how to ?
// const a = {
// value: 0
// }
// a.valueOf = function () {
// return this.value += 1
// }
let a = {
value: 0,
valueOf(){
return ++this.value
}
}
// var a = [1, 2, 3]
// a.join = function(){ return this.shift() }
// var a = {
// value: 0
// }
// a.vauleOf = function(){
// return this.value += 1
// }
console.log('a == 1 && a == 2 && a == 3', a == 1 && a == 2 && a == 3) // true
// a === 1 && a === 2 && a === 3; // true ?
// var value = 0 //window.value
// Object.defineProperty(window, 'a', {
// get: function(){
// return this.value += 1
// }
// })
// console.log('a === 1 && a === 2 && a === 3', a === 1 && a === 2 && a === 3) // true
///////////////////////////////
闭包
///////////////////////////////
/**
1.闭包的概念:
闭包就是一个函数,两个函数彼此嵌套,内部函数就是闭包形成闭包条件是内部函数需要通过return给返回出来。
看下面的代码,你就懂了:
function f1(){
function f2(){
alert("我是js闭包!");
}
return f2;
}
var f=f1();
f(); //弹出:我是js闭包!
2. 闭包特点
闭包有权利调用其上级环境的变量信息。父级环境的信息已经固化为本身AO的成员了。
看下代码,更好理解:
function f1(){
var bb = "闭包";
function f2(){
alert('我是'+bb);
}
return f2;
}
var f = f1();
f(); //弹出:我是js闭包
3. 闭包使用规则
同一个闭包机制可以创建多个闭包函数出来,它们彼此没有联系,都是独立的。
并且每个闭包函数可以保存自己个性化的信息。
看下代码,理解下三个闭包彼此独立、没有联系:
function f1(num){
function f2(){
alert('数字:'+num);
}
return f2;
}
var fa = f1(10);
var fb = f1(20);
var fc = f1(30);
fa(); //数字:10
fb(); //数字:20
fc(); //数字:30
4. 闭包的使用例子,加深理解闭包
//创建数组元素
var num = new Array();
for(var i=0; i<4; i++){
//num[i] = 闭包;//闭包被调用了4次,就会生成4个独立的函数
//每个函数内部有自己可以访问的个性化(差异)的信息
num[i] = f1(i);
}
function f1(n){
function f2(){
alert(n);
}
return f2;
}
num[2](); //2
num[1](); //1
num[0](); //0
num[3](); //3
*/
function foo() {
var i = 1;
return function() {
i++;
console.log(i);
}
}
var aFn = foo(), bFn = foo();
aFn(); // 2
aFn(); // 3
bFn(); // 2
//--------------------------------------------------->
function funca(){
y = function(){
X=2;
};
return function(){
var x=3;
y();
console.log(this.x); // 3
}.apply(this, arguments);
}
funca();//undefined
//--------------------------------------------------->
/**
* 闭包 函数自执行 this指向
*/
var func = (function (a) {
this.a = a
return function (a) {
a += this.a
return a
}
})(function (a, b) {
return a
}(1, 2))
console.log('闭包多层嵌套: ', func(5)) // 6
// 理解过程
var func = (function (a) {
this.a = a
return function (a) {
a += this.a
return a
}
})(1)
var func = function (a = 1) {
this.a = 1
return function (a) {
a += 1
return a
}
}
// 即 func 自执行函数返回一个函数 function(a){ return a += 1 } 这个函数将传递的参数加 1 返回
funcc = function (a) {
return a += 1
}
console.log('分析后的func为一个函数', funcc(4)); // 5
///////////////////////////////
[‘1’, ‘2’, ‘3’].map(parseInt)
parseInt(param, radix)
相当于 parseInt(String(param).trim(), radix)
// parseInt()
const value = parseInt(string[, radix]);
其中 string是一个要解析的字符串,如果不是字符串,则使用toString()方法给转换成string,开头的空格会被忽略。
radix是一个介于2-36的整数。表示一个基数,要将字符串转换成这个基数的进制。默认是10。
返回值是一个整数或者NaN。
// map() 创建新数组, 结果是遍历的数组每个元素执行提供的函数返回的结果.
const new_array = arr.map(function callback(currentValue[,index[, array]]) {
// Return element for new_array
}[, thisArg])
['1', '2', '3'].map(parseInt)
这意味着,每个map的迭代,都要给parseInt传递两个参数,item和index,就是字符串和基数。
那这个表达式可以写成
['1', '2', '3'].map((item, index) => parseInt(item, index))
返回的结果应该是:
parseInt('1', 0) // 1
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN 因为3不是2进制里的数,所以就报错。
所以该表达式返回的数组为:
['1', '2', '3'].map(parseInt) // [1, NaN, NaN]
加里·伯恩哈德例子也就很好解释了,这里不再赘述
['10','10','10','10','10'].map(parseInt); // [10, NaN, 2, 3, 4]
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////
///////////////////////////////
//
///////////////////////////////