记一下巩固 js 时碰到的一些基础知识
null 和 undefined
null
表示”没有对象”,即该处不应该有值。
- 作为函数的参数,表示该函数的参数不是对象。
- 作为对象原型链的终点。
undefined
表示”缺少值”,就是此处应该有一个值,但是还没有定义。
- 变量被声明了,但没有赋值时,就等于
undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于
undefined。
- 对象没有赋值的属性,该属性的值为
undefined。
- 函数没有返回值时,默认返回
undefined。
数据转换
1 + '1'; // '11'
true + true; // 2
'a' + +'b'; // -> "aNaN"
4 * '3'; // 12
4 * []; // 0
4 * [1, 2]; // NaN
4 * [1]; // 4
4 + [1, 2, 3]; // 41,2,3
bind,apply,call
let a = {};
let fn = function () {
console.log(this);
};
fn.bind().bind(a)(); // => ?
{% post_link js-call-bind-apply 我的 bind,apply,call 笔记 %}
amd,cmd,umd,commonJS
AMD 模块以浏览器第一的原则发展,异步加载模块; CommonJS 模块以服务器第一原则发展,选择同步加载; UMD 是 AMD 和 CommonJS 的糅合;
new
- 新生成了一个对象
- 链接到原型
- 绑定 this
- 返回新对象
手写一个 new
function create() {
let obj = {};
let Con = [].shift.call(arguments);
obj.__proto__ = Con.prototype;
let result = Con.apply(obj, arguments);
return result instanceof Object ? result : obj;
}
- 创建一个空对象
- 获取构造函数
- 设置空对象的原型
- 绑定 this 并执行构造函数
- 确保返回值为对象
instanceof
instanceof
可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype
手写实现
function myInstanceof(left, right) {
let prototype = right.prototype;
left = left.__proto__;
while (true) {
if (left === null || left === undefined) return false;
if (prototype === left) return true;
left = left.__proto__;
}
}
为什么 0.1 + 0.2 != 0.3
我不打算就这个问题进行过多的讨论和研究
解决方法:
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3; // true
相关文章
Why is 0.1 + 0.2 Not Equal to 0.3 in Most Programming Languages?
宏任务微任务
不做过多探讨,贴文章,这篇特别好,是群友 sky 提供的。
下面的都是中文文章,看看也无妨
- https://juejin.cn/post/6844904095199789069
- https://juejin.cn/post/6844903657264136200
- https://zhuanlan.zhihu.com/p/78113300
- http://www.ruanyifeng.com/blog/2014/10/event-loop.html
- https://segmentfault.com/a/1190000014940904
- https://www.mdeditor.tw/pl/p7Tm
- https://www.mdeditor.tw/pl/p7Tm
- https://segmentfault.com/a/1190000019761557
- https://segmentfault.com/a/1190000012806637
- https://juejin.cn/post/6844903954292146184
- https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
- https://zhuanlan.zhihu.com/p/257069622
原型是什么
感谢 霜霜家小迷妹-Pomo 的回答
先有 object,建 prototype 以继之,做抽象之母。可用对象(没有自己 new 一个)应从 prototype 继承,补属性、方法。如是。
1.首先原型是什么?
在 JavaScript 中原型是一个 prototype 对象,用于表示类型之间的关系。
原型对象的用途是为每个实例对象存储共享的方法和属性,它仅仅是一个普通对象而已。并且所有的实例是共享同一个原型对象,因此有别于实例方法或属性,原型对象仅有一份。
2.原型链又是什么?
JavaScript 万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在 JavaScript 中是通过 prototype 对象指向父类对象,直到指向 Object 对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。
附个链接,虽然可能没啥用 - https://zh.javascript.info/native-prototypes
js 是如何运行的
感谢 霜霜家小迷妹-Pomo 的回答,我怀疑这位不是计算机硕士就是计算机博士,太强了
一位群友透露:pomo 说她只是一个小文员,写程序是业余爱好
取一 js 文件,以 JIT 处之,拆 token, 解析外部引用,建 ast,优化,或转 bytecode(如 p-code),后交引擎解释——乃执行者也。
jit 是啥 - just in time
面向对象
先了解一下什么是对象
起初,“面向对象”是指在程序设计中采用封装、继承、多态等设计方法。现在,面向对象的思想已经涉及到软件开发的各个方面。如,面向对象的分析(OOA,ObjectOriented Analysis),面向对象的设计(OOD,Object Oriented Design)、以及面向对象的编程实现(OOP,Object Oriented Programming)。
对象和类解释: 1)对象:对象是人们要进行研究的任何事物,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。
2)类:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。
对象和类的关系: 类与对象的关系就如模具和铸件的关系,类的实力化的结果就是对象,而对对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象。
面向对象编程的特性
三大基本特性:封装,继承,多态
封装
封装,就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
继承
继承,指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用父类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。
多态
多态,是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。