JavaScript 笔记03(创建对象/原型模式/js 继承/BOM)
2018-08-22 11:36
615 查看
js 笔记3
接笔记2
13.创建对象
- 工厂模式
function createNewObject(name, age, job) { let o = new Object(); o.name = name; o.age = age; o.job = job o.sayName = function() { console.log(name); } return o; }; let me = createNewObject('Ethan', 24, 'java'); console.log(me.name); // Ethan
- 构造函数模式
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { console.log(this.name); } }; let p = new Person('Ethan', 24, 'java') console.log(p.name); // Ethan
以这种方式调用构造函数实际上会经历以下 4 个步骤:
- 创建一个新对象;
- 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
- 执行构造函数中的代码(为这个新对象添加属性);
- 返回新对象。
通过构造函数模式创建出来的 p 对象有一个 constructor 属性,该属性指向 Person。并且通过构造函数可以将实例标识为一种特定的类型,这是工厂模式做不到的。
console.log(p.constructor == Person); // true
console.log(p instanceof Person); //true
如果不使用 new 来声明构造函数:this 就会指向 global 对象。
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { console.log(this.name); } }; Person('zzz', 24, 'js'); global.sayName(); let o = new Object(); Person.call(o, 'yyy', 23, 'vue'); o.sayName(); // yyy global.sayName(); // zzz
以上构造函数有个问题:使用构造函数的主要问题,就是每个方法都要在每个 实例上重新创建一遍 。
所以,做如下改进:
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; }; function sayName() { console.log(this.name); } let p1 = new Person('Ethan', 24, 'java'); p1.sayName(); // Ethan let p2 = new Person('aa', 22, 'bb'); console.log(p1.sayName == p2.sayName); // true,而用之前的方式结果为 false
14.原型模式
是什么:每个函数都有一个
prototype(原型)属性,该属性可以看成一个指针,指向一个对象,这个对象的用途是包含了特定对象的所有实例共享的属性和方法。可以把
prototype理解为通过构造函数而创建的那个对象实例的原型对象。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法。所以,我们不必再构造函数中定义对象实例的信息,而是将这些信息直接添加到原型对象中。
因此,之前的构造函数可以写成这样:
function Person() { }; Person.prototype.name = 'Ethan'; Person.prototype.age = 24; Person.prototype.job = 'java'; Person.prototype.sayName = function () { console.log(this.name); } let p1 = new Person(); p1.sayName(); // Ethan let p2 = new Person(); console.log(p1.sayName == p2.sayName); // true
理解:看图吧,构造函数、构造函数的对象、
prototype、
constructor、
[[Prototype]](_PROTO_)之间的爱恨情仇。
当我们调用一个对象的属性时,都会进行一次搜索,先搜索该对象是否有相同名称的属性,再去搜索该对象的原型是否有该属性。所以如果我们给一个对象的原型已经有的属性重新赋值,并不会影响对象的原型,只会应该该对象的属性。可以通过
hasOwnProperty()来判断该属性是实例属性还是原型属性。还有一个方法是
in,比如
"name" in person1,这个方法不管该属性是在实例属性中还是原型属性中,都会返回
true。
除此之外,还有个方法返回对象所有的课枚举属性。
function Person() { }; Person.prototype.name = 'Ethan'; Person.prototype.age = 24; Person.prototype.job = 'java'; Person.prototype.sayName = function () { console.log(this.name); }; let keys = Object.keys(Person.prototype); console.log(keys); // [ 'name', 'age', 'job', 'sayName' ]
当然,上面的原型语法比较复杂,可以写成下面这种相对简单的:
function Person() { }; Person.prototype = { // constructor: Person, // 最后一段话也可以用这行代替 name: 'Ethan', age: 24, job: 'java', sayName: function() { console.log(this.name); } }; // 因为每创建一 个函数,就会同时创建它的 prototype 对象,这个对象也会自动获得 constructor 属性,所以加上这个 Object.defineProperty(Person.prototype, "constructor", { enumerable: false, value: Person });
原型模式的缺点:原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。 说简单点就是修改一个对象的属性会影响到另一个对象的该属性。
15.组合使用构造函数模式和原型模式
创建自定义类型最常用的方法,构造函数模式用来定义实例属性,原型模式用来定义方法和共享的属性。这样,每个实例都有自己的一份实例属性的副本,但同时又共享着对方法的引用,节省了内存。还可以向构造函数传递参数。
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; } Person.prototype = { constructor: Person, sayName: function () { console.log(this.name); } } let p1 = new Person('aa', 10, 'java'); let p2 = new Person('bb', 20, 'js'); p1.sayName(); // aa p2.sayName(); // bb p1.name = 'cc'; p1.sayName(); // cc p2.sayName(); // bb
16.js 中的继承
就说两种吧:
- 组合继承
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ //继承属性 SuperType.call(this, name); this.age = age; } //继承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); instance1.sayName(); instance1.sayAge(); //"red,blue,green,black" //"Nicholas"; //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); instance2.sayName(); instance2.sayAge(); //"red,blue,green" //"Greg"; //27
- 更完善的:寄生组合继承
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); this.age = age; } SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); };
17.闭包
关于闭包,直接看这篇吧,我觉得说的挺易懂的。
18. BOM 中常用 api
window.innerHeigt
window.innerWidth
window.outerHeigt
window.outerWidth
window.location===
document.location
location.assign
// 下面三行代码效果完全相同 window.location = "http://www.google.com"; location.href = "http://www.google.com"; location.assign = "http://www.google.com";
Navigator:获取浏览器的信息找这个。
screen:屏幕的信息找这个。
history.go(-1)
history.go(1)
history.back()
history.forward()阅读更多
相关文章推荐
- 【学习笔记六】 - js中 创建对象的模式与继承 及 js中实现块级作用域和函数私有变量 《js高程》6-7笔记
- javascript(js)创建对象的模式与继承的几种方式
- js创建对象的构造函数模式+原型模式和组合继承\Hybrid Pattern & combination inheritance
- JavaScript构造函数+原型创建对象,原型链+借用构造函数模式继承父类练习
- JavaScript高级程序设计之面向对象的程序设计之创建对象之原型模式 第6.2.3讲笔记
- 【JS】JavaScript中对象的创建与原型模式
- JavaScript高级程序设计之面向对象的程序设计之创建对象之组合使用构造函数模式和原型模式 第6.2.4讲笔记
- Javascript---字面量创建对象、组合构造函数+原型模式、动态原型模式
- 韩顺平_轻松搞定网页设计(html+css+javascript)_第29讲_二维数组转置_js面向对象编程介绍 类(原型对象)和对象_学习笔记_源代码图解_PPT文档整理
- javascript创建对象之动态原型模式(五)
- js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
- #笔记#圣思园 JavaWeb 第57讲——JS继承:对象冒充、call方法、apply方法、原型链方式、混合方式
- JavaScript高级程序设计之面向对象的程序设计之创建对象之寄生构造函数模式 第6.2.6讲笔记
- javascript学习笔记10(基于组合与动态原型创建对象)
- javascript之对象学习笔记(二)--对象原型,继承
- js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
- JavaScript高级程序设计之面向对象的程序设计之创建对象之 构造函数模式第6.2.2讲笔记
- javascript创建对象之函数构造模式和原型模式结合使用(四)
- javascript创建对象——组合使用构造函数和原型模式
- JavaScript高级程序设计之面向对象的程序设计之创建对象之工厂模式第6.2.1讲笔记