new
function myObjCreate(proto){
function F(){}
F.prototype = proto
return new F();
}
function myNew(F,...args){
let obj = myObjCreate(F.prototype)
let res = F.call(obj,...args);
return typeof res === 'object' && res !== null ? res : obj;
}
如果构造函数返回的是基本类型(如字符串、数字、布尔值、null、undefined),这些返回值会被忽略,new操作符会返回新创建的对象。
类只能用new运算来创建,而不能使用“()”来做函数调用
new AClass() // ok
AClass() // TypeError: Class constructor AClass cannot be invoked without 'new'
obj.foo() // ok
new obj.foo() // TypeError: obj.foo is not a constructor
类:只可以做new运算;
方法:只可以做调用“( )”运算;
一般函数:(除部分函数有特殊限制外,)同时可以做new和调用运算。
区分 3 者
类:定义类的方法是使用class关键字。
方法:附加在对象上的函数,通常定义在对象字面量或者类内部
一般函数:一般函数是普通的函数声明或函数表达式
function myExtends(Child, Parent) {
// 创建一个新的对象,该对象的原型指向 Parent.prototype
Child.prototype = Object.create(Parent.prototype);
// 修复 Child.prototype.constructor 指向 Child 自身
Child.prototype.constructor = Child;
// 允许 Child 访问 Parent
Child.proto = Parent;
}
类
在类声明中,如果是类静态声明,也就是使用static声明的方法,那么主对象就是这个类,例如AClass。
就是一般声明,那么该方法的主对象就是该类所使用的原型,也就是AClass.prototype。
第三种情况,如果是对象声明,那么方法的主对象就是对象本身。
类声明中 extends 是 null,那么构造方法中没有 this 也不能调用 super()。
class MyClass extends null {
}
new 后报错 Uncaught TypeError: Super constructor null of MyClass is not a constructor
class MyClass extends null {
constructor() {
}
}
new 后报错 Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
对象和数组的区别
对象和数组都是用来存储数据的两种结构。数组是一种特殊的对象,它用数字作为标签(索引)来存储数据,比如a[0]表示数组a中的第一个元素。而对象用名字作为标签来存储数据,比如obj.name表示对象obj中的一个叫name的属性。
JavaScript中的数据结构主要有两种:
索引数组(用数字索引的数组)
关联数组(用名字作为标签的对象)
null
null是一个对象类型
原子对象:原子对象是最基本的对象,它的原型是null。一个原子对象没有任何属性,也没有原型。
class MyClass extends null {}
let instance = new MyClass(); console.log(Object.getPrototypeOf(MyClass.prototype)); // 输出 null console.log(instance); // 输出 {}
+
[] + {} // 空数组[]被转换成空字符串'',空对象{}被转换成字符串'[object Object]',然后这两个字符串连接起来。
'[object Object]'
{} + [] // {}被视为一个空的代码块,所以没有任何作用,而空数组[]被转换成数字0。
0
{} + {} // 第一个 {} 被视为代码块,后面的 +{} 尝试将 {} 转换为数值,结果是 NaN,这里的+号作为一元运算符
NaN
[] + [] // 两个空数组都被转换成空字符串,连接起来仍然是空字符串。
''
上面执行反应了+符号在字符串拼接,数字计算,一元运算符
上面有两个案例是因为 js 的【自动分号插入(ASI)】机制,可以看成下面的结果
{}; +[]
PrimitiveValue
五种PrimitiveValue内部槽:number,string,boolean,symbol,bigint。
上面这 5 种在经过ToPrimitive(hint) 转换时直接调用x.valueOf()
返回原始值。
在默认情况下,JavaScript更倾向于把对象转换为数字类型。因为hint 默认是 number
valueOf/toString
如果用户代码试图得到“number”类型,但x.valueOf()返回的是一个对象,那么就还会调用x.toString(),并最终得到一个字符串。
let x = {
valueOf() {
return {}; // 返回一个对象
},
toString() {
return "Hello";
}
};
// 尝试将 x 转换为数字
console.log(x + 5); // 输出 "Hello5"
环境:
全局环境(Global Environment):声明环境+对象环境
声明环境:函数环境(Function Environment)/模块环境(Module Environment)/Eval环境(Eval Environment)
声明环境(Declarative Environment):抽象的概念,用于存储通过 var、let、const 声明的变量和函数声明。
对象环境(Object Environment):全局对象(如浏览器中的 window 对象或 Node.js 中的 global 对象),其中包含全局变量和函数作为其属性。
变量环境(Variable Environment):主要用于记录通过 var 声明的变量和函数声明。
词法环境(Lexical Environment):主要用于记录通过 let、const 和函数声明的变量。
HTML 脚本元素属性:async 与 defer 与 type=’module’
https://cdn-images-1.medium.com/v2/resize:fit:1117/1*nmzAKz_RSbZ-E-m5B6pPaA.png
标签:prototype,对象,valueOf,HTML,toString,constructor,new,null,声明 From: https://www.cnblogs.com/beilo/p/18236579