原型和原型链
JavaScript 常被描述为一种基于原型的语言——每个对象
拥有
一个原型对象,对象以其原型为模板,从原型继承方法和
属性。原型对象也可能拥有原型,并从中继承方法和属性
,一层一层,以此类推。这种关系常被称为原型链,它解
释了为何一个对象会拥有定义在其他对象中的属性和方法
。
__proto__ 是每个实例上都有的属性,prototype
是构造函数的属性。
例子
// 先定义一个简单的构造函数
function aFn() {}
aFn.prototype
// {
// constructor: f aFn()
// [[Prototype]]: Object
// }
// 然后创建一个实例
const a1 = new aFn();
a1.__proto__
// {
// constructor: f aFn()
// [[Prototype]]: Object
// }
实例通过 __proto__ 属性
可以访问到构造函数的原型对象。
而构造函数调用 prototype 属性
就可以查看该构造函数的原型对象。
我感觉 __proto__ 属性
可以理解为原型链,可以通过该属性向上查看
构造函数的原型对象。prototype 属性可以理解为原型,
可以通过该属性查看当前构造函数的原型对象。
当然构造函数不仅有 prototype 属性
还有 __proto__ 属性,
因为所有构造函数的原型是 Object类。
在 JavaScript 中,几乎所有的对象都是 Object
类型的实例,它们都会从 Object.prototype 继承
属性和方法。
Object 没有对应的原型。
Object.prototype.__proto__ === null // true
JS 中定义函数的方法
第一种 使用 function 关键字定义函数
function sum(param1, param2) {
return param1 + param2;
}
注意:
1. 在当前作用域下会创建一个包含这个函数的变量,变
量的标识名就是函数的名称。
2. 这个函数会被提升到当前作用域的顶层。
第二种 字面量创建函数(函数表达式)
let fun = function(arg1, arg2) {
alert(arg1 + arg2);
}
这种创建方式是不需要函数名的,并且函数不会被提升到作用域的顶层。
第三种 箭头函数
let sum = (param1, param2) => {
return param1 + param2;
}
注意:
1. 箭头函数没有自己的 this。
2. 箭头函数没有 prototype 属性。
第四种 Function 构造器
let sum = new Function('param1', 'param2', 'return param1 + param2');
注意:
从性能方面考虑的话,这种定义函数的方式没有函数声明
或函数表达式那么高效,使用 Function 构造器定义函数
在每次构造器调用的时候,构造器都会被解析一次,因为
字符串的函数体每次都需要进行解析,不能像其他方式那
样,只需要解析其他的代码就可以了。
第五种 Generator 函数
function* idMaker() {
let index = 0;
while(true) {
yield index ++;
}
}
let gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
注意:
function* 和 yield 关键字对于 generator 函数来说
是唯一的。Generator 函数通过在 function 尾部添加
一个 * 来定义 Generator 函数,这让我们在 generator
函数体中可以用 yield 在请求上生成多个值。
null 和 undefined
首先 undefined 和 null 都是假值(false),都能作为条
件进行判断,所以在绝大多数情况下两者在使用上没有区
别。
console.log(null == undefined); // true
// 松散模式 (loose equality)
console.log(null === undefined); // true
// 严格模式 (strict equality)
console.log(null === undefined); // false
字面上,undefined 就是 "未定义"的意思,
所以当没有定义一个东西之前,它就是undefined
undefined 会出现的场景有五种:
1. 没有定义
2. 定义了但没有赋值
3. 直接赋值或返回 undefined
4. 函数空return或干脆没有return
5. 没有对应的属性
咱们没有明说由系统来猜时,会得到undefined;而 null
则需要主动要求才给。
null 是一个普通值,需要主动使用,和平时使用的值没
有多大区别。
undefined 是一个特殊值,是 JS 中最后的备选方案。
当我们向js要求一个不存在的东西时,会得到 undefined
|| 和 &&
当使用 || 进行运算时,如果第一个值为false,就返回第二个值,如果第一个值为true,就返回第一个值。
当使用 && 进行运算时,如果第一个值为false,就返回第一个值,如果第一个值为true,就返回第二个值。
学长!!!好久不见!(。・∀・)ノ゙
好久不见呀