一:创建对象、
①构造函数
function Obj(){
//绑定属性及方法
this.name = "tigger";
this.action = function(){
alert(this.name + "is run...");
}
}
//使用new关键字构造对象实例
var p = new Obj();
//通过对象实例使用对象的属性和方法
p.action();
②Object对象创建对象
该方式为工厂模式进行对象的创建
function CreateObj(){
//构造一个Object对象
var obj = new Object();
//在对象上面邦定属性及方法
obj.number = 11;
obj.action = function(){
do something ....
}
// 返回对象
return obj;
}
//调用工厂方法构造对象并访问对象的属性和方法
CreateObj().action();
③原型创建对象
//创建构造方法,不绑定任何属性和方法
function Obj(){
}
//通过原型晚期绑定属性和方法
Obj.prototype.number = "111";
Obj.prototype.name = "Obj";
Obj.prototype.fun= function(){ do something ...}
//实例化对象实例
var p = new Obj();
//使用对象的属性和方法
p.action();
④字面量创建对象
var obj ={ name:"zhangsan", age:18, saySalf:function(){} }
⑤ 混合法模式 (原型模式 + 构造函数模式)
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.prototype.friends = ["Shelby", "Court"];
}
Person.prototype.sayName = function(){ alert(this.name); }
二:对象继承
①原型继承
原型链继承:
function Person(){
this.foot = 2;
this.head=1;
}
function Student(name,no){
this.name=name;
this.no=no;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
var stu1 = new Student("张三","s001");
对上一种方法的改进
由于Person对象中,不变的属性都可以直接写入Person.prototype。所以,可以让Student()跳过 Person(), 直接继承Person.prototype
function Person(){ }
Person.prototype.foot = 2;
Person.prototype.head = 1;
function Student(name,no){ this.name=name; this.no=no; }
Student.prototype = Person.prototype;
Student.prototype.constructor = Student;
var stu1 = new Student("张三","s001");
优点:效率比较高(不用执行和建立Person的实例了)
缺点:Student.prototype和Person.prototype现在指向了同一个对象,任何对Student.prototype的修改, 都会反映到Person.prototype
②空对象继承
function Person(){}
Person.prototype.foot = 2;
Person.prototype.head = 1;
function Student(name,no){
this.name=name;
this.no=no;
}
var F= function(){}; //空对象作为中介
F.prototype = Person.prototype;
Student.prototype = new F();
var stu1 = new Student("张三","s001");
Student.prototype.constructor = Student;
利用空对象作为中介 空对象,几乎不占内存 修改Student的prototype对象,不会影响到Person的prototype对象
③构造函数继承
call(替换的对象,参数列表)
apply(替换的对象,参数数组)
PS 两种方法修改this指向
function Person(){
this.foot = 2;
this.head=1;
this.favorColor=["red","yellow"];
}
function Student(name,no){
//Person.call(this); this代表当前对象Student
Person.apply(this);
this.name=name;
this.no=no;
}
var stu1 = new Student("张三","s001");
stu1.favorColor.push("blue");
var stu2 = new Student("李四","s002");
缺点: 父类的方法没有被共享,造成内存浪费
④组合继承
将原型链继承和构造函数继承组合在一块, 原型链实现对原型属性和方法的继承, 借用构造函数实现对实例属性的继承
function Person(){
this.foot = 2;
this.head=1;
this.favorColor=["red","yellow"];
}
Person.prototype.sayColor=function(){
alert("Hello,我最爱的颜色是:"+this.favorColor);
}
function Student(name,no){
Person.call(this);
this.name=name;
this.no=no;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
var stu1 = new Student("张三","s001");
var stu2 = new Student("李四","s002");
⑤拷贝继承
把父对象的所有属性和方法,拷贝进子对象,将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象
function Person(){}
Person.prototype.foot = 2;
Person.prototype.head = 1;
Person.prototype.saySelf=function(){
alert("Hello,我有:"+this.foot+"只脚和"+this.head+"个头");
}
function Student(name,no){
this.name = name;
this.no = no;
}
function extend2(Child,Parent){
var p = Parent.prototype;
var c = Child.prototype;
for(var i in p){ c[i] =p[i]; }
}
extend2(Student,Person);
var stu1 = new Student("张三","s001");
stu1.saySelf();
⑤es6的extend和super继承
class Animal {
constructor (name){
this.name = name
}
showName () {
alert(this.name)
}
}
class Cat extends Animal {
constructor (name) {
super(name)
this.type = '宠物'
}
}
var cat = new Cat('飞翔的哔哔鸡')
cat.showName()
三:js对象常用方法梳理
方法名 | 方法解释 |
---|---|
hasOwnProperty() | 返回一个布尔值,指示对象自身属性中是否具有指定的属性 |
Object.assign(obj , ...) | 将所有可枚举属性的值从不定个数的源对象复制到目标对象并返回。(浅拷贝) |
Object.keys(obj) | 返回对象obj的属性和方法键组成的数组 |
面试题:new创建对象具体执行了什么
1.在内存中开辟一块空间并初始化一个空对象
2.新对象会被执行_proto_连接,指定为new 关键字后面对象的prototype
3.将this指向新对象
4.将对象的二属性和方法绑定到新对象上
5.默认返回这个新对象