网站首页 > 技术文章 正文
typeof
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
语法
typeof 运算符后接操作数:
typeof operand
typeof(operand)
参数
operand 一个表示对象或原始值的表达式,其类型将被返回。
描述
下面总结了 typeof 可能的返回值。有关类型和原始值的更多信息,可查看 JavaScript 数据结构 页面。
类型 | 结果 |
Undefined | "undefined" |
Null | "object" (见下文) |
Boolean | "boolean" |
Number | "number" |
BigInt (ECMAScript 2020 新增) | "bigint" |
String | "string" |
Symbol (ECMAScript 2015 新增) | "symbol" |
宿主对象(由 JS 环境提供) | 取决于具体实现 |
Function 对象 (按照 ECMA-262 规范实现 [[Call]]) | "function" |
其他任何对象 | "object" |
原始值
除对象类型(object)以外的其它任何类型定义的不可变的值(值本身无法被改变)。例如(与 C 语言不同),JavaScript 中字符串是不可变的(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。我们称这些类型的值为“原始值”。
特性
1、typeof 总是返回一个字符串。
2、typeof 能正确判断原始值的类型,null 除外;引用类型数据能正确判断 Function、函数的类型,其他的都会返回 'object'。
示例
// 数值
console.log(typeof 37 === 'number') // true
console.log(typeof 3.14 === 'number') // true
console.log(typeof (42) === 'number') // true
console.log(typeof Math.LN2 === 'number') // true
console.log(typeof Infinity === 'number') // true
console.log(typeof NaN === 'number') // true 尽管它是 "Not-A-Number" (非数值) 的缩写
console.log(typeof Number(1) === 'number') // true Number 会尝试把参数解析成数值
console.log(typeof 42n === 'bigint') // true
// 字符串
console.log(typeof '' === 'string') // true
console.log(typeof 'bla' === 'string') // true
console.log(typeof `template literal` === 'string') // true
console.log(typeof '1' === 'string') // true 注意内容为数字的字符串仍是字符串
console.log(typeof (typeof 1) === 'string') // true typeof 总是返回一个字符串
console.log(typeof String(1) === 'string') // true String 将任意值转换为字符串,比 toString 更安全
// 布尔值
console.log(typeof true === 'boolean') // true
console.log(typeof false === 'boolean') // true
console.log(typeof Boolean(1) === 'boolean') // Boolean() 会基于参数是真值还是虚值进行转换
console.log(typeof !!(1) === 'boolean') // true 两次调用 ! (逻辑非) 操作符相当于 Boolean()
// Symbols
console.log(typeof Symbol() === 'symbol') // true
console.log(typeof Symbol('foo') === 'symbol') // true
console.log(typeof Symbol.iterator === 'symbol') // true
// Undefined
console.log(typeof undefined === 'undefined') // true
console.log(typeof declaredButUndefinedVariable === 'undefined') // true
console.log(typeof undeclaredVariable === 'undefined') // true
// 对象
console.log(typeof { a: 1 } === 'object') // true
// 使用 Array.isArray 或者 Object.prototype.toString.call
// 区分数组和普通对象
console.log(typeof [1, 2, 4] === 'object') // true
console.log(typeof new Date() === 'object') // true
console.log(typeof /regex/ === 'object') // true 历史结果请参阅正则表达式部分
// 使用 new 操作符
// 除 Function 外的所有构造函数的类型都是 'object'
var func = new Function()
console.log(typeof func) // 返回 'function'
var A = function() {}
var b = new A()
console.log(typeof b) // 返回 'object'
// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
console.log(typeof new Boolean(true) === 'object') // true
console.log(typeof new Number(1) === 'object') // true
console.log(typeof new String('abc') === 'object') // true
// 函数
console.log(typeof function () { } === 'function') // true
console.log(typeof class C { } === 'function') // true
console.log(typeof Math.sin === 'function') // true
// Null
// JavaScript 诞生以来便如此
console.log(typeof null === 'object') // true
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。(参考来源)
console.log(typeof 0); // number
console.log(typeof BigInt(Number.MAX_SAFE_INTEGER)); // bigint
console.log(typeof '0'); // string
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof function () { }); // function
console.log(typeof Symbol); // function
console.log(typeof Symbol()); // symbol
console.log(typeof Date); // function
console.log(typeof Date()); // string
console.log(typeof new Date); // object
console.log(typeof new Date()); // object
console.log(typeof RegExp); // function
console.log(typeof RegExp()); // object
console.log(typeof new RegExp); // object
console.log(typeof new RegExp()); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object
如果我们想判断一个对象的正确类型,可以考虑使用 instanceof,因为内部机制是通过 判断实例对象的 __proto__ 和生成该实例的构造函数的 prototype 是不是引用的同一个地址(也就是原型链的方式)来判断的。
错误
在 ECMAScript 2015 之前,typeof 总能保证对任何所给的操作数返回一个字符串。即便是没有声明的标识符,typeof 也能返回 'undefined'。使用 typeof 永远不会抛出错误。
但在加入了块级作用域的 let 和 const 之后,在其被声明之前对块中的 let 和 const 变量使用 typeof 会抛出一个 ReferenceError。块作用域变量在块的头部处于“暂存死区”,直至其被初始化,在这期间,访问变量将会引发错误。
typeof undeclaredVariable === 'undefined';
typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceError
let newLetVariable;
const newConstVariable = 'hello';
class newClass{};
instanceof
instanceof 运算符用于检测构造函数 prototype 属性是否出现在某个实例对象的原型链上。可以用来判断都属于 Object 类型和一些特殊情况的对象,如:数组和对象,但不能用于基础数据类型。
语法
object instanceof constructor
参数
object 某个实例对象
constructor 某个构造函数
描述
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
示例
B instanceof A:判断 B 是否为 A 的实例,可以用于继承关系中
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true
// 定义构造函数
function C(){}
function D(){}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype 不在 o 的原型链上
o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object // true,同上
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.
D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上
需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__ 伪属性,是可以实现的。比如执行 obj.__proto__ = {} 之后,obj instanceof Foo 就会返回 false 了。
A 是 B 的父对象,c 是 B 的实例,c instanceof A 与 c instanceof B 结果均为 true。
function A() { }
function B() { }
B.prototype = new A()
const c = new B()
console.log(c instanceof B); // true
console.log(c instanceof A); // true
console.log(A instanceof B); // false
console.log(B instanceof A); // false
console.log(B.__proto__ === A.prototype); // false
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(c instanceof Object); // true c 属于
console.log(B instanceof Object); // true
console.log(A instanceof Object); // true
演示 String 对象和 Date 对象都属于 Object 类型和一些特殊情况
下面的代码使用了 instanceof 来证明:String 和 Date 对象同时也属于Object 类型(他们是由 Object 类派生出来的)。
但是,使用对象文字符号创建的对象在这里是一个例外:虽然原型未定义,但 instanceof Object 返回 true。
var simpleStr = "This is a simple string";
var myString = new String();
var newStr = new String("String created with constructor");
var myDate = new Date();
var myObj = {};
var myNonObj = Object.create(null);
console.log(simpleStr instanceof String) // 返回 false, 非对象实例,因此返回 false
console.log(myString instanceof String) // 返回 true
console.log(newStr instanceof String) // 返回 true
console.log(myString instanceof Object) // 返回 true
console.log(myObj instanceof Object) // 返回 true, 尽管原型没有定义
console.log(({}) instanceof Object) // 返回 true, 同上
console.log(myNonObj instanceof Object) // 返回 false, 一种创建非 Object 实例的对象的方法
console.log(myString instanceof Date) // 返回 false
console.log(myDate instanceof Date) // 返回 true
console.log(myDate instanceof Object) // 返回 true
console.log(myDate instanceof String) // 返回 false
Object.prototype.toString.call(object)/Object.prototype.toString.apply(object)
toString.call() 或 toString.apply() 方法几乎可以精准判断各类数据的类型。
console.log(Object.prototype.toString.call("kevin")) // [object String]
console.log(Object.prototype.toString.call(18)) // [object Number]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call(NaN)) // [object Number]
console.log(Object.prototype.toString.call({ name: "kevin" })) // [object Object]
console.log(Object.prototype.toString.call(function () { })) // [object Function]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(new Date)) // [object Date]
console.log(Object.prototype.toString.call(/\d/)) // [object RegExp]
console.log(Object.prototype.toString.call(Math)) // [object Math]
function Person() { }
console.log(Object.prototype.toString.call(new Person)) // [object Object]
var o = { [Symbol.toStringTag]: "A" }
console.log(Object.prototype.toString.call(o)) // [object A]
console.log(window.toString()) // "[object Window]"
console.log(Object.prototype.toString.call(window)) // "[object Window]"
console.log(Object.prototype.toString.call(Symbol())); // "[object Symbol]"
// 封装
function getTypeof(data) {
let dataType = Object.prototype.toString.call(data);
return dataType.slice(8, -1)
}
console.log(getTypeof(18)) // Number
console.log(getTypeof("kevin")) // String
console.log(getTypeof(new Date)) // Date
console.log(getTypeof([])) // Array
console.log(getTypeof({})) // Object
function Person() { }
console.log(getTypeof(new Person)) // Object
console.log(getTypeof(new Person())) // Object
语法
obj.toString()
返回值
一个表示该对象的字符串
描述
每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。以下代码说明了这一点:
var o = new Object();
console.log(o.toString()); // [object Object]
备注:如 ECMAScript 5 和随后的 Errata 中所定义,从 JavaScript 1.8.5 开始,toString() 调用 null 返回[object Null],undefined 返回 [object Undefined]。请参阅下面的使用toString()检测对象类型。
示例
覆盖默认的 toString 方法
可以自定义一个方法,来取代默认的 toString() 方法。该 toString() 方法不能传入参数,并且必须返回一个字符串。自定义的 toString() 方法可以是任何我们需要的值,但如果它附带有关对象的信息,它将变得非常有用。
以下代码定义了 Dog 对象类型,并创建了一个 Dog 类型的 theDog 对象:
function Dog(name,breed,color,sex) {
this.name = name;
this.breed = breed;
this.color = color;
this.sex = sex;
}
var theDog = new Dog("Gabby", "Lab", "chocolate", "female");
// 如果当前的对象调用了 toString() 方法,它将会返回从 Object继承而来的 toString() 方法的返回默认值:
console.log(theDog.toString()); // 返回 [object Object]
// 下面的代码中定义了一个叫做 dogToString() 的方法来覆盖默认的 toString() 方法。
// 这个方法生成一个 "property = value;" 形式的字符串,该字符串包含了当前对象的 name、breed、color 和 sex 的值。
Dog.prototype.toString = function dogToString() {
var ret = "Dog " + this.name + " is a " + this.sex + " " + this.color + " " + this.breed;
return ret;
}
// 也可以这样写
Dog.prototype.toString = function dogToString() {
return `Dog ${this.name} is a ${this.sex} ${this.color} ${this.breed}`;
}
// 使用上述代码,任何时候在字符串上下文中使用 theDog.toString() 时,
// JavaScript 都会自动调用 dogToString() 方法(dogToString() 可以是一个匿名函数),并且返回以下字符串:
// "Dog Gabby is a female chocolate Lab"
console.log(theDog.toString()); // 返回 "Dog Gabby is a female chocolate Lab"
// 也可以这样写
Dog.prototype.toString = function dogToString() {
return '[object Dog]';
}
Dog.prototype[Symbol.toStringTag] = 'Dog'
// 也可以这样写
theDog[Symbol.toStringTag] = 'Dog'
console.log(theDog.toString()); // 返回 [object Dog]
console.log(Dog.prototype.toString()); // 返回 [object Dog]
console.log(Dog.prototype.toString.call(theDog)); // 返回 [object Dog]
console.log(Object.prototype.toString.call(theDog)); // 返回 [object Object]
使用 toString() 检测对象
可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
检测原理
Object.prototype.toString.call(obj) 类型检测的原理是什么?首先我们来看一下 toString() 方法:
var num = 1
console.log(num.toString()) // '1'
var str = 'kevin'
console.log(str.toString()) // 'kevin'
var bool = false
console.log(bool.toString()) // 'false'
var arr = [1, 2, 3]
console.log(arr.toString()) // '1,2,3'
var obj = { name: 'kevin' }
console.log(obj.toString()) // '[object Object]'
var fn = function(){}
console.log(fn.toString()) // 'function(){}'
console.log(JSON.toString()) // '[object JSON]'
console.log(Atomics.toString()) // '[object Atomics]'
console.log(null.toString()) // Cannot read property 'toString' of null
console.log(undefined.toString() // Cannot read property 'toString' of undefined
console.log(window.toString()) // '[object Window]'
从以上示例可以知道 toString 是将数据转换为字符串(null 和 undefined 除外),并且各种类型的数据转换为字符串的方式又不一样。即若参数不为 null 或 undefined,则将参数转为对象,再作判断。对于原始类型,转为对象的方法即装箱。
转为对象后,取得该对象的 [Symbol.toStringTag] 属性值(可能会遍历原型链)作为 tag,如无该属性,或该属性值不为字符串类型,则依下表取得 tag,然后返回 "[object " + tag + "]" 形式的字符串。
新标准引入了 [Symbol.toStringTag] 属性,是为了把此方法接口化,用于规范新引入的对象对此方法的调用。但对于“老旧”的对象,就只能直接输出值,以保证兼容性。
// 1. 三个容器对象。这类对象用作命名空间,用于存储同一类方法。
JSON[Symbol.toStringTag]; // => "JSON"
Math[Symbol.toStringTag]; // => "Math"
Atomics[Symbol.toStringTag]; // => "Atomic"
// 这三个对象的 toString() 都没有重写,直接调用 toString() 方法也可以得到相同的结果。
JSON.toString(); // => "[object JSON]"
Math.toString(); // => "[object Math]"
Atomics.toString(); // => "[object Atomics]"
// 2. 两个新引入的类型 BigInt 和 Symbol。
BigInt.prototype[Symbol.toStringTag]; // => "BigInt"
Symbol.prototype[Symbol.toStringTag]; // => "Symbol"
// 3. 四个集合(Collection)对象。
Set.prototype[Symbol.toStringTag]; // => "Set"
Map.prototype[Symbol.toStringTag]; // => "Map"
WeakSet.prototype[Symbol.toStringTag]; // => "WeakSet"
WeakMap.prototype[Symbol.toStringTag]; // => "WeakMap"
// 4. 在不同的实现中,有些第三方对象也部署了此属性。
// 比如在浏览器中:
Window.prototype[Symbol.toStringTag]; // => "Window"
HTMLElement.prototype[Symbol.toStringTag]; // => "HTMLElement"
Blob.prototype[Symbol.toStringTag]; // => "Blob"
// 5. 模块命名空间对象(Module Namespace Object)。
// 新引入的模块命名空间对象(Module Namespace Object)也是部署了此属性的。
import * as module from "./export.js";
module[Symbol.toStringTag]; // => "Moduel"
// 6. 在 Node.js 中
global[Symbol.toStringTag]; // => "global"
我们再来看一下 Object 以及其原型上的 toString 方法:
Object.toString(); // "function Object() { [native code] }"
Object.prototype.toString(); // "[object Object]"
var o = new Object();
console.log(o.toString()); // 返回 [object Object]
console.log(o.__proto__.toString()); // 返回 [object Object]
console.log(o.__proto__.toString === Object.prototype.toString); // true
我们可以看出 Object 和它的原型链上各自有一个 toString 方法,Object 输出的是其函数体 "function Object() { [native code] }",而 Object 原型上输出的是其类型 "[object Object]"。
数据类型 | 例子 | 输出 |
字符串 | "foo".toString() | "foo" |
数字 | 1.toString() | Uncaught SyntaxError: Invalid or unexpected token |
布尔值 | true.toString() | "true" |
undefined | undefined.toString() | Uncaught TypeError: Cannot read property 'toString' of undefined |
null | null.toString() | Uncaught TypeError: Cannot read property 'toString' of null |
String | String.toString() | "function String() {[native code]}" |
Number | Number.toString() | "function Number() {[native code]}" |
Boolean | Boolean.toString() | "function Boolean() {[native code]}" |
Array | Array.toString() | "function Array() {[native code]}" |
Function | Function.toString() | "function Function() {[native code]}" |
Date | Date.toString() | "function Date() {[native code]}" |
RegExp | RegExp.toString() | "function RegExp() {[native code]}" |
Error | Error.toString() | "function Error() {[native code]}" |
Promise | Promise.toString() | "function Promise() {[native code]}" |
Object | Object.toString() | "function Object() {[native code]}" |
Math | Math.toString() | "[object Math]" |
Window | Window.toString() | "function Window() { [native code] }" |
window | window.toString() | "[object Window]" |
数据类型调用 toString() 方法的返回值,由此我们看出不同的数据类型都有其自身toString()方法
// Boolean 类型,tag 为 "Boolean"
console.log(Object.prototype.toString.call(true)); // => "[object Boolean]"
// Number 类型,tag 为 "Number"
console.log(Object.prototype.toString.call(1)); // => "[object Boolean]"
// String 类型,tag 为 "String"
console.log(Object.prototype.toString.call("")); // => "[object String]"
// Array 类型,tag 为 "String"
console.log(Object.prototype.toString.call([])); // => "[object Array]"
// Arguments 类型,tag 为 "Arguments"
console.log(Object.prototype.toString.call((function() {
return arguments;
})())); // => "[object Arguments]"
// Function 类型, tag 为 "Function"
console.log(Object.prototype.toString.call(function(){})); // => "[object Function]"
// Error 类型(包含子类型),tag 为 "Error"
console.log(Object.prototype.toString.call(new Error())); // => "[object Error]"
// RegExp 类型,tag 为 "RegExp"
console.log(Object.prototype.toString.call(/\d+/)); // => "[object RegExp]"
// Date 类型,tag 为 "Date"
console.log(Object.prototype.toString.call(new Date())); // => "[object Date]"
// 其他类型,tag 为 "Object"
console.log(Object.prototype.toString.call(new class {})); // => "[object Object]"
// window 全局对象
console.log(Object.prototype.toString.call(window); // => "[object Window]")
在 JavaScript 中,所有类都继承于 Object,因此 toString 方法应该也被继承了,但由上述可见事实并不像我们想的那样,其实各数据类型使用 toString() 后的结果表现不一的原因在于:所有类在基础 Object 的时候,改写了 toString 方法。尽管如此,但 Object 原型上的方法是可以输出数据类型的,因此我们想判断数据类型时,也只能使用原型上的 toString 方法:Object.prototype.toString.call(object) 。
直接调用
toString(); // "[object Undefined]"
(function(){
console.log(toString()); // [object Undefined]
})();
也就是说直接调用toString()方法,等价于
Object.prototype.toString.call(); // "[object Undefined]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
即:直接调用 toString() 方法这里不可以理解成为全局作用域调用 toString() 方法,即 window.toString()
所以直接调用 toString() 应该就是变相的 undefined.toString() 方法(这里说的是相当于,实际 undefined 并没有方法,调用会报错)。
验证
// 定义一个数组
var arr = [1, 2, 3]
// 数组原型上是否具有 toString() 方法
console.log(Array.prototype.hasOwnProperty('toString')) //true
// 数组直接使用自身的 toString() 方法
console.log(arr.toString()) // '1,2,3'
// delete操作符删除数组原型上的 toString()
delete Array.prototype.toString
// 删除后,数组原型上是否还具有 toString() 方法
console.log(Array.prototype.hasOwnProperty('toString')) //false
// 删除后的数组再次使用 toString() 时,会向上层访问这个方法,即 Object 的 toString()
console.log(arr.toString()) // '[object Array]'
当我们把 Array 自身的 toString() 方法删除之后,再次使用它时,由原型链它会向上查找这个方法,即 Object 的 toString(),也便将 Object 上的 toString() 方法作用在数组上,得出其数据类型 [object Array] 。
为什么需要call/apply
经常有人用 toString.call/apply(类型) 去代替 Object.prototype.toString.call/apply(类型) 使用,其实这样是不严谨的,容易导致一些问题,如下所示
function toString(){
console.log("1")
}
toString(); // 1
toString.call({}); // 1
toString.call([]); // 1
我们可以发现,当我们自定义了 toString() 方法时,直接调用 toString() 方法,就不会再默认调用 Object 类的 toString() 方法,而是会使用我们自定义的方法,这样可能得不到我们想要的结果,所以我们还是应当尽量使用 Object.prototype.toString.call/apply(类型)。
正因为 Object.prototype.toString() 本身允许被重写,像 Array、Boolean、Number 的 toString 就被重写过,所以需要调用 Object.prototype.toString.call(arg) 或 Object.prototype.toString.apply(arg) 或 Reflect.apply() 来判断 arg 的类型,call 将 arg 的上下文指向 Object,所以 arg 执行了 Object 的 toString() 方法。
至于 call,就是改变对象的 this 指向,当一个对象想调用另一个对象的方法,可以通过 call 或者 apply 改变其 this 指向,将其 this 指向拥有此方法的对象,就可以调用该方法了。
var x = {
toString() {
return "X";
},
};
x.toString(); // => "X"
Object.prototype.toString.call(x); // => "[object Object]"
Object.prototype.toString.apply(x); // => "[object Object]"
Reflect.apply(Object.prototype.toString, x, []); // => "[object Object]"
判断原生JSON对象
var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON);
console.log(isNativeJSON); // 输出结果为 "[object JSON]" 说明JSON是原生的,否则不是;
- 上一篇: JS垃圾回收机制
- 下一篇: 快速了解ES6的Set与WeakSet
猜你喜欢
- 2024-11-18 浏览器垃圾回收
- 2024-11-18 JavaScript中各种源码实现(前端面试笔试必备)
- 2024-11-18 2021年要了解的34种JavaScript优化技术
- 2024-11-18 你可能不知道的JS开发技巧
- 2024-11-18 Javascript面试题总结1
- 2024-11-18 深入JavaScript教你内存泄漏如何防范
- 2024-11-18 关于前端174道 JavaScript知识点汇总(一)
- 2024-11-18 前端面试计划(二)ES6
- 2024-11-18 2022前端大厂VUE 面试题
- 2024-11-18 javascript中的内置对象和数据结构
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-