面试题
正则表达式
exec方法
正则.exec(字符串),方法返回一个数组,比普通数组多了index、input、groups等字段
数量
?
意为 0 或 1 次
+
意为 1 次以上
*
意为 0 次以上
array
sort方法
不传参数:如果没有提供 compareFn,所有非 undefined 的数组元素都会被转换为字符串,并按照 UTF-16 码元顺序比较字符串进行排序。例如“banana”会被排列到“cherry”之前。在数值排序中,9 出现在 80 之前,但因为数字会被转换为字符串,在 Unicode 顺序中“80”排在“9”之前。所有的 undefined 元素都会被排序到数组的末尾。sort() 方法保留空槽。如果源数组是稀疏的,则空槽会被移动到数组的末尾,并始终排在所有 undefined 元素的后面。
传参数:(a,b) => number
,a-b就是升序,b-a就是降序。
变量提升
变量
console.log(num)
var num = 1
相当于
var num
console.log(num)
num = 1
函数
//函数声明式:
function foo () {}
//变量形式声明:
var fn = function () {}
fn()
var fn = function () {
console.log(1)
}
// 输出结果:Uncaught TypeError: fn is not a function
foo()
function foo () {
console.log(2)
}
// 输出结果:2
JS 引擎会搜集所有的变量声明,并且提前让声明生效。而剩下的语句需要等到执行阶段、等到执行到具体的某一句时才会生效。这就是变量提升背后的机制。
变量与函数同名
函数会提升到变量之前,所以同名的函数会被变量覆盖。
forof和forin的区别?
- for…in 对象 => key,理解对象是一个整体,所以用 in 遍历,拿到的是 key
- for…of 数组 => value,数组是一个集合,元素是个体,用 of 遍历,拿到的是 value
触摸事件
包括start end move cancel四个touch事件
不会冒泡的事件
resize、error、load、unload、mouseenter、mouseleave、blur、focus
finally
var i = 100;
function foo() {
bbb: try {
console.log("position1");
return i++;
} finally {
break bbb;
}
console.log("position2");
return i;
}
foo();
因为 finally 会是 try/catch 中的 return 失效,所以第一个 return 就失效了,但是 i++ 会执行。所以输出结果是 position1、position2、101
this
this有四种情况
- 当在函数调用的时候指向widow
- 当方法调用的时候指向调用对象
- 当用apply和call上下文调用的时候指向传入的第一个参数
- 构造函数调用指向实例对象
同名变量
var foo = {n:1};
(function(foo){
console.log(foo.n);
foo.n = 3;
var foo = {n:2};
console.log(foo.n);
})(foo);
console.log(foo.n);
局部变量低于形参,let才会涉及到暂时死区,var不会,所以不会报错。 输出结果为1、2、3
call方法
thisArg的值为null或者undefined调用时函数内部的this指向window对象
URL API
URL和URLSearchParams,URLSearchParams是处理query字符串的工具类,可以对它的实例用a.forEach进行遍历,还有has、append、has的方法。
typeof和instanceof的区别
typeof
和 instanceof
是 JavaScript 中用于检查数据类型的两种不同的方法。
-
typeof
:typeof
是一个操作符,用于确定给定变量的数据类型。- 它返回一个表示变量类型的字符串。
- 常用的返回值包括:“undefined”、“boolean”、“number”、“string”、“object”、“function” 和 “symbol”。
typeof
对于数组和 null 的返回值会有些许特殊,数组返回 “object”,null 返回 “object”,这是 JavaScript 语言本身的一个历史遗留问题。
typeof 42; // "number" typeof "hello"; // "string" typeof true; // "boolean" typeof {}; // "object" typeof []; // "object" typeof null; // "object" (历史遗留问题) typeof function() {}; // "function" typeof undefined; // "undefined"
-
instanceof
:instanceof
是一个操作符,用于检查一个对象是否属于某个特定的类(构造函数)的实例。- 它返回一个布尔值,表示对象是否是该类的实例。
- 它会检查整个原型链,如果对象是指定类的实例或者是指定类的子类的实例,则返回
true
,否则返回false
。
var arr = []; arr instanceof Array; // true function Person(name) { this.name = name; } var john = new Person("John"); john instanceof Person; // true
所以,typeof
用于检查基本数据类型和函数,而 instanceof
则用于检查对象是否是某个类的实例。
__proto__和prototype以及原型和原型链
在 JavaScript 中,每个对象都有一个 __proto__
属性,用于指向其原型对象。而原型对象又有一个 prototype
属性,用于指向构造函数的原型。理解这些概念有助于理解 JavaScript 中的原型继承和原型链。
-
__proto__
:__proto__
是每个 JavaScript 对象上都有的一个非标准属性(在 ECMAScript 6 中被标准化为Object.getPrototypeOf
方法),它指向该对象的原型。- 通过
__proto__
属性,对象可以访问其原型链上的属性和方法。 - 在许多现代浏览器中,可以使用
Object.getPrototypeOf(obj)
方法来获取对象obj
的原型,而不必直接访问obj.__proto__
。
-
prototype
:prototype
是函数对象特有的一个属性,当一个函数被定义时,它会自动创建一个prototype
属性,该属性的值是一个对象,这个对象包含了函数的原型方法和属性。- 如果这个函数被用作构造函数(通过
new
关键字调用),则创建的对象将会继承这个prototype
对象上的属性和方法。
-
原型(Prototype):
- 每个 JavaScript 对象都有一个原型。对象通过原型实现属性和方法的继承。
- 当访问一个对象的属性或方法时,如果该对象本身没有定义这个属性或方法,则会沿着原型链向上查找,直到找到匹配的属性或方法为止。
- 对象的原型可以通过
__proto__
属性来访问。
-
原型链(Prototype Chain):
- JavaScript 中的对象之间通过原型链相互关联。
- 当需要查找对象的属性或方法时,JavaScript 引擎会沿着对象的原型链向上查找,直到找到匹配的属性或方法为止。
- 这种原型链的查找机制使得对象可以共享属性和方法,实现了简单而强大的继承模型。
例如,假设有如下代码:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
var john = new Person("John");
john.sayHello(); // 输出 "Hello, my name is John"
console.log(john.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
在这个例子中:
john
对象的原型指向Person.prototype
,因此它可以访问Person.prototype
中定义的sayHello
方法。Person.prototype
的原型指向Object.prototype
,因为所有的 JavaScript 对象都是从Object
构造函数派生而来的。
这就是原型和原型链在 JavaScript 中的基本概念和工作原理。
new 函数
function myNew(constructor_) {
var obj = {};
obj.__proto__ = constructor_.prototype
return obj
}
什么是作用域?
作用域(Scope)是在程序中定义变量的可访问范围,即确定在代码中的哪些部分可以访问或引用变量。在 JavaScript 中,作用域规定了变量的可见性和生命周期。
JavaScript 中有两种主要的作用域:
-
全局作用域(Global Scope):
- 全局作用域是在代码中任何地方都可以访问的作用域。在浏览器环境中,全局作用域通常指的是全局对象
window
,而在 Node.js 环境中,全局作用域指的是global
对象。 - 在全局作用域中定义的变量或函数可以在程序的任何地方被访问。
- 全局作用域是在代码中任何地方都可以访问的作用域。在浏览器环境中,全局作用域通常指的是全局对象
-
局部作用域(Local Scope):
- 局部作用域是在函数内部定义的作用域,只能在函数内部访问其中定义的变量或函数。
- 每次调用函数时都会创建一个新的局部作用域,函数执行完毕后,局部作用域会被销毁,其中定义的变量也会被释放。
JavaScript 中的作用域是通过词法作用域(也称为静态作用域)来实现的,这意味着作用域是由代码中变量的声明位置来确定的,而不是由其运行时的调用位置决定的。因此,在函数内部定义的变量在函数外部是不可见的,而在函数内部可以访问外部作用域的变量。
作用域的概念对于理解变量的可见性、避免命名冲突、优化代码和调试错误等都至关重要。JavaScript 中的作用域规则帮助开发者编写更可维护、更可靠的代码。