6. new方法
function Func() {};
var func = new Func();
看看new
操作符具体做了以下几件事情:
-
创建一个空对象
var obj = new Object();
-
设置原型链
obj.__proto__ = Func.prototype;
-
让
Func
中的this
指向obj
,并执行Func
的函数体。var result = Func.call(obj);
-
判断Func的返回值类型:
如果result
是值类型,返回obj
。如果是引用类型,就返回这个引用类型的对象。if (typeof(result) == "object"){ func = result; } else { func = obj;//返回空object }//无论如何返回的都是object类型,
7.面向对象高级
对象创建模式
-
object对象创建模式。先创建空对象,再动态向对象中添加方法。**优点:**在不清楚对象的内部数据时使用。缺点:语句太多有点麻烦的
var p = {}//字面量方式创建 var p = new Object//new方式创建,多了一步设置原型链和this指向设置 p = {}
-
创建的同时添加属性/方法。**优点:**启示时内部数据一定,**缺点:**创建多个对象时会有重复代码
-
工厂函数模式。工厂函数是指返回值是对象的函数。**优点:**创建多个对象十分方便。**缺点:**对象没有一个具体的类型, 都是Object类型
function createPerson(name, age) { //返回一个对象的函数===>工厂函数 var obj = { name: name, age: age, setName: function (name) { this.name = name } } return obj } var p1 = createPerson('Tom', 12) var p2 = createPerson('Bob', 13)//这样即可创建两个对象
-
自定义构造函数。**优点:**每个对象都有其具体的类型。**缺点:**每个对象都会存储同一个方法,占用内存
function Person(name, age) { this.name = name this.age = age this.setName = function (name) { this.name = name } } var p1 = new Person('Tom', 12)
-
自定义构造函数+原型。在构造函数中只初始化一般属性,将方法存储在构造函数
prototype
中,节约内存。
对象继承模式
原型链继承
方便子类型使用父类型的方法
- 关键点:子类型的原型是父类型的一个实例(
子类型.prototype
= new父类型
) - 由于子类型的
prototype
指针就指向了父类型的实例对象上,由于原型链的存在,最终导致子类型的constructor
指向了父类型函数。解决:var 子类型.prototype.constructor = 子类型
call()
借用其他函数的方法
-
关键点:在子类型(其实并不是)中使用
call()
方法调用父类型的构造函数 -
//方便帮助子类型获取父类型的属性 function Person(name, age) { this.name = name this.age = age } function Student(name, age, price) { Person.call(this, name, age) // 相当于: this.Person(name, age) /*this.name = name this.age = age*/ this.price = price } var s = new Student('Tom', 20, 14000) console.log(s.name, s.age, s.price)
原型链+call()
方法
8.进程和线程
-
进程:程序的一次执行, 它占有一片独有的内存空间
-
线程: CPU的基本调度单位, 是程序执行的一个完整流程
-
进程与线程
- 一个进程中一般至少有一个运行的线程: 主线程
- 一个进程中也可以同时运行多个线程, 我们会说程序是多线程运行的
- 一个进程内的数据可以供其中的多个线程直接共享
- 多个进程之间的数据是不能直接共享的
-
浏览器运行是单进程还是多进程?
单进程::firefox 老版IE
多进程:chrome 新版IE
-
如何查看浏览器是否是多进程运行的 任务管理器==>进程
-
浏览器运行是单线程还是多线程? 都是多线程运行的
-
* 先执行初始化代码: 包含一些特别的代码
* 设置定时器
* 绑定事件监听
* 发送ajax请求
* 后面在某个时刻才会执行回调代码
时间循环
- 主程序栈;callback queue:事件队列,消息队列,任务队列
webworkers
- 将一些计算量较大的操作放在
webworkers
线程中进行计算,不会因为主线程计算时间长而导致页面冻结 - worker内代码不能操作DOM, 不能跨域加载JS,子线程受主线程控制,没有改变js单线程的本质
- API
Worker
: 构造函数, 加载分线程执行的js文件Worker.onmessage
: 用于接收另一个线程的回调函数Worker.postMessage
: 向另一个线程发送消息
var worker = new Worker('worker.js')//work.js是一个分线程的url
// 绑定接收消息的监听
worker.onmessage = function (event) {
console.log('主线程接收分线程返回的数据: '+event.data)
alert(event.data)
}
// 向分线程发送消息
worker.postMessage(number)
console.log('主线程向分线程发送数据: '+number)
}