最近参加了一次为时两天的 JavaScript 培训,回顾课程内容并进行整理,其中参考了如下两篇老师的文章。
简介
函数是第一等公民。
JavaScript 的核心是 函数 和 对象 。
|
|
简化版 jquery 选择器实现
通过对 javascript 原生操作的封装,实现简化版的 jquery 类库。这里的代码并不复杂,个人感觉主要是要有类库的概念和实现思路,考虑将项目中使用的工具类逐步封装成类库。
|
|
对象
js 是解释型动态语言,可随时添加属性或方法,很灵活。
|
|
推荐使用如下字面量形式的定义方式。
|
|
遍历对象的属性和方法。
|
|
函数
函数的三种定义方式如下:
|
|
函数体的内部只有在函数被调用时才会进入,下面 demo 的运行结果是先后输出 1、2、3、4、5。使用 Chrome 调试断点进入时,打开 Sources 注意观察 Scope 的变化,可以看到运行到 func1()时 Scope 只有 Globle,当进入到调用的方法时,会有 Local,里面是函数内部定义的变量或方法,当函数内部用到了外面的变量时,会有 Closure,里面是引用的外部变量。
|
|
作用域
this 取决于在哪调用,而不是在哪定义,通过“对象.”调用的,this 都是这个对象,直接调用的 this 都是 window。
|
|
通过函数的 call、apply、bind 方法进行调用可改变作用域,call 和 apply 只是传递参数的方式不同。
|
|
模拟类
函数名的第一个字母大写,表示是用来构造对象的,不是用来执行的。
用方式一模拟类,o1 和 o2 有自己的 name 属性,但第三个输出结果为 false,这说明 o1.sayHello 和 o2.sayHello 指向不同内存,这样存在内存的浪费。
|
|
用方式一模拟类,第三个输出结果为 true,这时不存在内存浪费了,但破坏了封装,在外部也可以调用 sayHello 方法。
|
|
用方式三模拟类,通过即时函数封装作用域后,可以比较好的模拟类了。
|
|
用方式四模拟类,在即时函数封装作用域的基础上,又添加了命名空间。
|
|
原型
所有对象都有原型对象__proto__
,只有函数对象有原型属性prototype
,当这个函数被用作构造函数来创建实例时,该函数的原型属性(prototype)将被作为原型赋值给所有对象实例,也就达到了重用方法的作用,即所有实例的原型引用的是函数的原型属性。
|
|
在执行完 var Person = function() {};
语句时,会分配三块内存,Person 变量的内存、function 函数的内存、protptype 指向对象的内存,这个对象的 constructor 又指向 Person 指向的函数。
|
|
JavaScript 是动态语言,取决于运行时,不是定义时,因此下面的代码中示例一的对象 o 是有 sayHello 方法的。通过如示例二、示例三、示例四的方式给 Function、String、jquery 等全局函数的 prototype 添加方法来实现共有的新功能。
|
|
|
|
|
|
|
|
实现类
利用原型实现类,注意下面方式一到方式四的区别,方式一到方式三的 o 对象已经有了 sayHello 方法,达到了重用方法的目的,但使用了__proto__
,理论上 JavaScript 中是不让用的。
|
|
方式二只是将 proto 作为 Person 的属性使用的。
|
|
|
|
|
|
方式四使用 new 创建的对象,也就是说函数 Person 被用作构造函数来创建实例了,这时该函数 prototype 将被作为原型__proto__
赋值给对象的实例,也就相当于如下代码。注意当函数名的第一个字母大写时,表示是用来构造对象的,不是用来执行的,该函数的 prototype 是给构造出来的对象用的,函数自己用不了。
|
|
当定义一个当函数被用作构造函时,这个函数会默认在函数体开头和结尾添加如下代码,如果函数 return 的不是对象,在使用 new 实例化对象时这个 return 语句会被忽略,因为需要返回一个对象。
|
|
实现继承
封装自己的框架,要有类、方法、复用。
|
|
封装商业框架,有 Model 和 View。
|
|
练习
|
|
|
|