- new
- 当
new
去调用一个函数:这个时候函数中的this
就是创建出来的对象。 - 函数的返回值直接就是
this
(隐式返回)
function Person(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
// 隐式返回当前的this,所以return可以省略
// return this;
}
var p1 = new Person('小明');
var p2 = new Person('小强');
-
构造函数
-
new
后面调用的函数就叫做构造函数
-
-
原型
-
prototype
去改写对象下面的功用的方法或者属性,让公用的方法或者属性在内存中只存在一份(提高性能) - 原型 :css中的class
- 普通的方法 : css中的style
- 优先级: 对象自身绑定的属性或方法,要高于在原型上绑定的属性或方法
-
function 构造函数(属性){
this.属性=属性;
}
构造函数.原型.方法 = function(){
console.log(this.属性);
};
var 对象1 = new 构造函数();
对象1.方法();
-
原型链
- 实例对象于原型之间的连接,叫做原型链。
-
__proto__
(隐式链接) -
Object
对象类型是原型链的最外层
-
hasOwnProperty
- 看是不是对象自身下面的属性
var arr = [];
arr.num = 10;
Array.prototype.num2 = 20;
console.log(arr.hasOwnProperty('num')) //true
console.log(arr.hasOwnProperty('num2')) //false
console.log(arr.hasOwnProperty == Object.prototype.hasOwnProperty);//true 不是自身而是最外层的Object中的
-
constructor
- 查看对象的构造函数
function Person() {}
Person.prototype.constructor = Person; //这句会隐式自动生成
var p = new Person();
console.log(p.constructor);
-
instanceof
- 对象与构造函数在原型链上是否有关系
p instanceof Object // true
-
toString()
- 把对象转成字符串
- 利用toString做类型的判断 (荐)
var arr = [];
console.log( Object.prototype.toString.call(arr) == '[object Array]' ); //'[object Array]'
//举例为什么说这种类型判断的方式是最佳的
window.onload = function(){
var oF = document.createElement('iframe');
document.body.appendChild( oF );
var ifArray = window.frames[0].Array;
var arr = new ifArray();
console.log( arr.constructor == Array ); //false
console.log( arr instanceof Array ); //false
console.log( Object.prototype.toString.call(arr) == '[object Array]' ); //true
};
//封装方法
var classType = [];
'Boolean Number String Function Array Date RegExp Object Error'.split(' ').forEach(function(name) {
classType['[object ' + name + ']'] = name.toLowerCase();
});
function getType(obj) {
if (obj == null) {
return String(obj);
}
return typeof obj === 'object' || typeof obj === 'function' ? classType[classType.toString.call(obj)] || 'object' : typeof obj;
}
-
继承
- 子类不影响父类,子类可以继承父类的一些功能 ( 代码复用 )
- 属性的继承 : 调用父类的构造函数
call
- 方法的继承 :
for in
-
常见继承方法
- 拷贝继承 (jquery也是采用拷贝继承extend)
//父类
function Person(name, sex) {
this.name = name;
this.sex = sex;
}
Person.prototype.showName = function() {
console.log(this.name);
};
//
var p1 = new Person('小明', '男');
//p1.showName();
//
//子类
function Star(name, sex, job) {
Person.call(this, name, sex);//继承父类属性
this.job = job;
}
//Star.prototype = Person.prototype; 通过这句可以做到继承,但是这是对象引用,一旦子类修改对象,会影响父类
//
extend(Star.prototype, Person.prototype); //采用拷贝继承则解决,影响父类的问题
//
Star.prototype.showJob = function() {};
var p2 = new Star('黄晓明', '男', '演员');
p2.showName();
//
function extend(obj1, obj2) {
for (var attr in obj2) {
obj1[attr] = obj2[attr];
}
}
- 类式继承
- JS是没有类的概念的 , 把JS中的构造函数看做是类
- 要做属性和方法继承的时候,要分开继承
function Person() { //父类
this.name = [1, 2, 3];
}
//
Person.prototype.showName = function() {
alert(this.name);
};
//
function Star() { //子类
Person.call(this); //属性继承
}
//关键的四句话
var F = function() {}; // 1. 创建一个新构造函数
F.prototype = Person.prototype; // 2. 新构造函数的原型指向要继承的父类构造函数
Star.prototype = new F(); // 3. 子类构造原型指向新构造函数的一个实例,可以使用父类的方法
Star.prototype.constructor = Star; // 4. 修正子类的指向,在上一步的时候它的原型指向了父类,所以需要修正回来
//
var p1 = new Star();
p1.showName();
alert(p1.name);
alert(p1.constructor);
p1.name.push(4);
var p2 = new Star();
alert(p2.name);
- 原型继承
- 父类采用json的生命方式
- 原型继承中如果属性是对象,则子类修改继承的属性同样会父类也会被修改
var Person = {
des:'小丽',
name: [1, 2, 3],
showName: function() {
alert(this.name);
}
};
//
function clone(o) {//创建一个clone函数
function F() {};
F.prototype = o;
return new F();
}
//
var p1 = clone(Person);
p1.des='小美';
p1.name.push(4);
p1.showName();
Person.showName();
console.log(p1.des);
console.log(Person.des);
参考
以上是对知识点的笔记,详细的js的面向对象可以百度或参考下面的文章
三生石上 - JavaScript继承详解系列
网友评论