高程3重读(ing...)
before
机会来的措手不及,但一番聊天后思考了很多。实习时候用多了jq,现在做毕设也用的框架,并且用框架的时候,也一部分只知道如何用,而没去究其原理,觉得自己一直认为重要的基础却被抛下了。这显得自己的简历中“重视基础”写的冠冕堂皇,于是重读高程3(其实以前没看多少,更喜欢读你不知道的js系列)。
希望这次经历后自己重拾初衷,端正作为一个工程师应有的态度,不能浮躁,毕竟理想是成为一名写一手好代码的人。
生疏点的记录
零散
- ie10+支持严格模式
定义 赋值
|
|
数据类型
1.null
的 typeof
是 object
|
|
2.Number类型中八进制,十六进制的表示(严格模式下错误)
|
|
3.js中可以保存正零(+0)和负零(-0)
|
|
4.浮点数精度不如整数 0.1+0.2结果不是0.3 是0.30000000000000004,但0.15和0.15就是0.3,所以不要测试浮点数值(IEEE754数值浮点计算的锅)
5.NaN大话题
- 和任何值都不等(包括自身) 可以利用这点在实际开发中做判断
- 正数/0返回Infinity,负数则-Infinity,0/0才返回NaN
操作符
&&
逻辑与,是个短路操作符(||也是短路操作符)123456789var found = true;var result = found && somevariable; //直接报错 因为没定义svconsole.log(result);var found1 = false;var rs1 = found1 && somevariable;console.log(rs1); //false,不会发生错误// ||中也相似 如果后面的undefined 前面的是true则不报错 false则报错~
面向对象
1.对象
数据属性
修改对象数据值属性的特性,使用 Object.defineProperty()
方法
|
|
访问器属性
不包含数据值,包含 getter
和 setter
函数。读取属性的时候调用get,写入属性的时候调用set。
这时设置一个属性会导致别的属性变化
|
|
定义多个属性
|
|
创建对象
工厂模式
1234567891011function foo(name, age) {var o = new Object();o.name = name;o.age = age;o.sayName = function () {console.log(this.name);};return o;}var per = foo('huk',23);缺点:没有解决对象识别问题
构造函数模式
12345678910function Foo2(name, age) {this.name = name;this.age = age;this.sayName = sayName();}function sayName(){console.log(this.name)}var per1 = new Foo2('huk1',23);var per2 = new Foo2('huk2',22);创建Foo2构造函数的实例,需要使用new操作符。per1和per2的constructor属性都指向Foo2,都是Foo2的实例。
缺点:全局作用域中定义的函数实际只给某个对象使用,如果要很多方法,就要定义很多全局下的函数,没有封装的意义。
原型模式
1234567891011function Foo3() {}Foo3.prototype.name = 'huk3';Foo3.prototype.age = 21;Foo3.prototype.sayName = function () {console.log(this.name);};var per = new Foo3();per.sayName(); //huk3var per2 = new Foo3();per2.sayName(); //huk3//per.sayName == per2.sayName trueFoo3原型对象的
constructor
属性 –> Foo3构造函数创建的实例per和per2的
[[prototype]]
指向Foo3.prototype- [[prototype]]无法访问,但可以用
isPrototype()
方法判断是否指向对象的prototype - 实例上定义新的属性(和原型同名的属性)会屏蔽原型上的属性,
hasOwnProperty()
可以检测是否是实例上定义的值 - in操作符
"name" in person
,原型和实例上的属性都遍历 - Object.keys():对象上所有可枚举的实例属性
- Object.getOwnPropertyNames():对象上所有可or不可枚举的实例属性
缺点:
123456789101112function Person(){}Person.prototype = {//这边prototype重写后,原来的链断了,所以要重新指向person。这时候Person构造函数上其实是有两个prototype对象的,此后定义的实例都指向新的,重写之前的仍指向旧的constructor:Person,name:'huk',friends:["huk1","huk2"]//....};var per1 = new Person();var per2 = new Person();per1.friends.push('huk3');//这时 per1.friends === per2.friends "huk1,huk2,huk3"
- [[prototype]]无法访问,但可以用
原型和构造组合使用
实例的属性通过构造函数定义,共享的属性和方法使用原型定义。
12345678function Person(name,age){this.name = name;this.age = age;}Person.prototype = {constructor:Person,sayName: function(){console.log(this.name)}}各实例之间的name和age属性互相不干扰
寄生构造函数模式
2.继承
寄生继承
|
|
Dom
- getElementsByClassName()兼容IE9+
- querySelector()兼容IE8+
- document.achiveElement获取焦点元素,document.hasFocus()得到文档是否获得焦点
- data-type在原生中的设置是ele.dataset.type = ‘…’
文档模式
过渡型或框架型HTML声明与过渡型或框架型XHTML声明均可使浏览器进入近似标准模式,同时,html5的DOCTYPE声明和严格型HTML声明以及严格型XHTML声明则会使浏览器进入标准模式。
不写DOCTYPE则进入混杂模式
|
|
事件
dom事件流
三个阶段:事件捕获、处于目标阶段、事件冒泡阶段
实际:捕获->接收到event->冒泡响应event返回到文档
ie8及以前版本不支持dom事件流
dom0级事件处理
给元素指定事件处理程序属性,给属性设置函数
|
|
dom2级事件处理程序
第三个参数为true的话代表捕获阶段调用事件处理程序,false代表冒泡阶段调用。
如果一个元素上定义多个click事件,从定义的从上至下顺序执行。
|
|
删除的时候需要删除完全相同的,所以要定义个函数表达式
ie8及以下不支持dom2事件处理
IE事件处理程序
作用域在全局上,所以 this === window
早起ie只支持事件冒泡,所以事件被添加到冒泡阶段
果一个元素上定义多个click事件,从定义的从下至上的相反顺序执行。
|
|
dom中的事件对象
|
|
事件对象
|
|