由于私有和特权成员在函数的内部,因此它们会被带到函数的每个实例中。
公有的原型成员是对象蓝图的一部分,适用于通过new关键字实例化的该对象的每个实例
静态成员只适用于对象的一个特殊实例
Function 对象(类)
ECMAScript 最令人感兴趣的可能莫过于函数实际上是功能完整的对象。
Function 类可以表示开发者定义的任何函数。是个函数构造器
构造函数.prototype = 原型对象
原型对象.constructor = 构造函数(模板)
原型对象.isPrototypeof(实例对象) 判断实例对象的原型 是不是当前对象
1 |
|
元素对象常用属性:
- obj.innerHTML;
- obj.outerHTML;
- obj.innerText;
- obj.textContent;
- obj.tagName;
1 | <p>hello world!<span>你好</span></p> |
1 | <script> |
判断IE与非IE浏览器:
1
2 if(document.all) alert('IE');
else alert("not IE");//用来判断IE与非IE浏览器
setTimeout
的定时器值推荐最小使用16.7ms的原因(16.7 = 1000 / 60, 即每秒60帧)。
1 | //匿名函数通过引用来调用 |
标签声明:
JavaScript
中的标签就是一个标识符,声明如下:
一个标识符后面跟一个冒号”:”。你可以在任何一个语句前面加上这样的标签。以使得该语句被“标签化”,例如:
1 | this_is_a_label: |
除了单一的语句外,标签也可以用于由大括号表示的符合语句,例如:
1 | label_statments: { |
在JS中有三种方法会涉及“初始化对象实例”的问题:
其一,是通过在构造器中利用this引用来初始化
其二,是通过构造原型实例来初始化
其三,是通过Object.create()并使用属性描述符的方式来构建对象并初始化
当参数表为空与没有参数表是一致的。因此下面两行代码是等意的:
1 | obj = new constructor; |
但是,我们不能认为constructor
后面的括号是函数调用的括号。因为如果这是函数调用的括号,那么下面的代码就应该是合理的了(但事实上,这行代码对于构造器来说是错误的用法):
1 | obj = new (constructor()); |
所以,不能错误地认为:new运算符是“产生对象实例,并调用constructor函数”——尽管看起来是这样
但是,如果我们的确不打算让new后面的函数作为构造器,而只是作为函数使用,可以这么做:
1 | //将foo视为普通函数 |
函数的提升(hoisting)
函数声明的行为并不等同于命名函数表达式,其区别在于提升(hoisting)行为,看下面例子:
1 | <script type="text/javascript"> |
Call和apply
apply
可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas'])
,或数组对象, 如 fun.apply(this, new Array('eat', 'bananas'))
。
1 | Function.prototype.construct = function (aArgs) { |
可以通过func1.call(this, arg1, arg2)
; 或者 func1.apply(this, [arg1, arg2])
; 来调用。其中 this 是你想指定的上下文,他可以任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
1 | location.hash=anchorname |
字面量对象
1 | //不管用什么方式调用它(使用new或直接调用),它都会返回一个实例对象: |
这种模式的问题是会丢失原型,因此在Waffle()的原型上的成员不会被继承到这些对象中。
Array()
构造函数的“陷阱”
我们对new Array()敬而远之还有一个原因,就是为了避免构造函数带来的陷阱。
如果给Array()构造函数传入一个数字,这个数字并不会成为数组的第一个元素,而是设置了数组的长度。也就是说,new Array(3)创建了一个长度为3的数组,而不是某个元素是3。如果你访问数组的任意元素都会得到undefined,因为元素并不存在。
1 | // 含有1个元素的数组 |
JavaScript使用函数来管理作用域,在一个函数内定义的变量称作“本地变量”,本地变量在函数外部是不能被访问的。
任何不通过var声明的变量都会成为全局对象的一个属性
另一种创建全局变量的反模式,就是在var声明中使用链式赋值的方法。在下面这个代码片段中,a是局部变量,但b是全局变量,而作者的意图显然不是这样:
1 | // 反模式 |
对象有两种类型的成员:实例成员和原型成员。实例成员直接存在于实例自身,而原型成员则从对象原型继承:
1 | var book = { |
此代码中,book对象有两个实例成员:title
和publisher
。
js给变量赋null值的作用在于:
就是赋值一个空指针,不赋值也可以,只是赋值了让人更容易理解这个变量是用来准备存放对象的,也方便调错。
style.display = ""
;是清除display样式,display将使用默认值(块元素会变成block,内联元素会变成inline)style.display="none"
; 中“none”是一个值,表示元素将隐藏
querySelector(IE8部分支持)
该方法返回满足条件的单个元素。按照深度优先和先序遍历的原则使用参数提供的CSS选择器在DOM进行查找,返回第一个满足条件的元素。
1 | element = document.querySelector('div#container');//返回id为container的首个div |
setTimeout()
是属于 window 的 method
1 | var obj = { |
用 document.readyState == "complete"
判断页面是否加载完成
编写高质量代码
1 | var my = {};//把多个全局变量都追加在一个名称空间下,将显著降低与其他应用程序产生冲突的概率 |
在一个函数中的任何位置定义的变量在该函数中的任何地方都可见。
判断是否是https
1 var isHttps = location.protocol.indexOf('https') > -1;
Location 对象包含有关当前 URL 的信息。
Location 对象属性
属性 描述
1 | hash 设置或返回从井号 (#) 开始的 URL(锚)。 |
Promise
所谓Promise,字面上可以理解为“承诺”,就是说A调用B,B返回一个“承诺”给A,然后A就可以在写计划的时候这么写:当B返回结果给我的 时候,A执行方案S1,反之如果B因为什么原因没有给到A想要的结果,那么A执行应急方案S2,这样一来,所有的潜在风险都在A的可控范围之内了。
上面这句话,翻译成代码类似:
1 | var resB = B(); |
该新特性属于 ECMAScript 2015(ES6)规范:
Promise 对象用来进行延迟(deferred) 和异步(asynchronous ) 计算.。一个 Promise 处于以下四种状态之一:
pending: 初始状态, 非 fulfilled 或 rejected.
fulfilled: 成功的操作.
rejected: 失败的操作.
settled: Promise已被fulfilled或rejected,且不是pending
new Promise(executor);
new Promise(function(resolve, reject) { … });
executor
函数对象,带有两个实参 resolve 和 reject. 第一个参数用来完成(fulfill)当前promise,第二个参数则用来拒绝(reject). 一旦我们的操作完成即可调用这些函数.
promise必须实现then方法(可以说,then就是promise的核心),而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致
then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用,另一个是失败时的回调,在promise由 “等待”态转换到“拒绝”态时调用。同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。
Object和Function都是构造函数,而所有的构造函数的都是Function的实例对象. 因此Object是Function的实例对象
实例对象的constructor([Function: Object])
的prototype是对象{}。构造函数的prototype( {} )的constructor是[Function Object]
继承函数的原理莫过于复制类的方法和属性。因此,只要做到这点,就可以实现类的继承了。可以在上面的代码中看见,我们通过遍历prototype来获取原型链中定义的方法和属性。通过apply调用父类的构造器进行构造器中属性和方法的复制
1 | function base (d, b, a) { |
使用示例:
1 | function People () { |
Each function has two properties: length and prototype
property是DOM中的属性,是JavaScript里的对象;
attribute是HTML标签上的特性,它的值只能够是字符串;
1 | Array.prototype.map(function(currentValue,index,array){}) |
map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值组合起来形成一个新数组。
`
Array.prototype.forEach(function(currentVal,idx,array){})
callback 函数会被依次传入三个参数:
数组当前项的值
数组当前项的索引
数组对象本身
函数也是对象,可以往函数上添加属性。将全局变量添加到函数的属性上,可以使之成为局部变量,减少命名冲突问题。