最近感受,不知道该学点什么,总是觉的本身什么都不会,又感受是会点什么,说是也知道面向对象,可是让系统的说一下这里面的东西,感受连不上线,成不了太系统的了解,因此就看了一下这的知识点,当本身的搬运工,伪装是发了一篇文章,等本身查看方便;bash
function creatPerson(name,age,job) {
var o = new Object();
o.name= name;
o.age= age;
o.job= job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var p1 = creatPerson("hh",23,"worker");
var p2 = creatPerson("xx",26,"worker1");
p1.__proto__===p2.__proto__===Object.prototype;
对象的constructor 属性最先是用来描述队形类型的,检测对象类型仍是 instanceof 更可靠
工厂模式建立的对象,constructor只有Object,这样的实例没有特定的类型;
复制代码
function Person(name,age,job){
this.age = age;
this.name = name;
this.job = job;
this.sayName = function(){
alert(this.name)
}
//this.sayName = sayName; //解决方式
}
var p1 = new Person("hh",23,"worker");
var p2 = new Person("xx",26,"worker1");
//function sayName(){alert(this.name)} //解决方式
new的执行:
{
var obj ={};
obj.__proto__ = Person.prototype;
Person.call(obj);
return obj
}
p1 instanceof Person //true;
p2 instanceof Person //true;
p1 instanceof Object //true;
p2 instanceof Object //true;
这样是得p1和p2实例有了特定的类型, Person;
复制代码
优势:他省略了构造函数初始化参数这个环节,原型中全部属性都被不少实例共享,共享对函数很是合适,基本属性也还行 经过在实例上添加同名属性,可隐藏原型中的对应属性值;app
缺点: 他的共享属性,对于包含引用类型值的属性 若是实例从新赋值没什么影响,和基本类型同样,若是是操做修改 就有些问题了,会使得全部实例获取到的该属性都被修改, 因此也不单独使用函数
function Person(){}
Person.prototype={
constructor:Person,
name:"ss",
friends:["s1","s2"],
sayName:function(){alert(this.name)}
}
var p1= new Person();
var p2= new Person();
p1.name = "p1"
console.log(p1.name) //p1
console.log(p2.name) //ss
p1.friends.push("s3");
console.log(p1.friends) //["s1","s2","s3"]
console.log(p2.friends) //["s1","s2","s3"]
复制代码
用法:ui
function Person(){}
Person.prototype.name="ceshi"
Person.prototype.age =12;
Person.prototype.sayName = function(){
alert(this.name)
}
//这样就是实现了代码的共享
复制代码
更简单的写法:
Person.prototype={
//constructor:Person,
name:"test",
age:12,
sayName:function(){alert(this.name)}
}
var friend = new Person();
friend instanceof Object //true
friend instanceof Person //true
friend.constructor==Person //false
friend.constructor==Object //true
这种简单的写法constructor 属性就不在指向Person,而是指向Object构造函数;
此时能够添加一个属性constructor( 如上面注释):可是此时的constructor 变成了可枚举的属性,原生是不可枚举的,能够考虑用Object.defineProperty()
复制代码
var p1 = new Person();
<!-- 1 -->
Person.prototype.hh="ss";
p1.hh//ss 是能够先建立实例在改边原型在访问的;
<!-- 2 -->
Person.prototype={
name:"ss"
}
p1.__proto__!=Person.prototype;
p1.name // undefined
复制代码
function Person(age,name){
this.name = name;
this.age = age;
this.friends=[1,2,3]
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name)
}
}
var p1 = new Person("ss",12);
var p2 = new Person("ss3",123);
p1.friends.push(2);
console.log(p1.friends) // [1,2,3,2]
console.log(p2.friends)// [1,2,3]
复制代码
function Person(name,age){
this.name = name;
this.age = age;
if(typeof this.sayName !="function"){//sayName没初始化 这里对一个方法判断就能够,而后初始化全部的,不必都每一个方法都判断
Person.prototype.sayName=function(){alert(this.name)}
Person.prototype.sayAge=function(){alert(this.age)};
.....
}
****注意****:此处不能使用对象字面量形式重写原型, 由于这中写法是先建立的实例,而后在修改的原型,要是用对象字面量重写原型,会切断现有实例和新原型之间的联系, 致使方法实例上无此方法;
}
复制代码
function Person(name,age){
var o = new Object();
o.name=name;
o.age=age;
o.sayName=function(){
alert(this.name)
};
return o;
}
var friends = new Person("xiaoming",12)
friends.asyName() // xiaoming
复制代码
稳妥对象: 没有公共属性,而且其方法中不引用this的对象;this
function Person(name,age){
var o = new Object();
o.sayName=function(){
alert(name)
};
return o;
}
var friends = new Person("xiaoming",12)
friends.asyName() // xiaoming
复制代码
继承通常包括: 接口继承:继承方法和签名; 实现继承:继承实际的方法;ECMAScript 只支持实现继承spa
js主要经过原型链实现继承,原型链的构建是经过将一个类型的实例赋值给另外一个构造函数的原型实现的prototype
Son.prototype = new Father();
//此时Son.constructor 被改写为了 Father;
Son.prototype.constructor = Son;
//给子类修改或者是添加方法的时候,要放在替换语句,改版子类原型语句以后,
//原型继承时,不能使用字面量方式建立原型方法,这样就从新写了原型链了
Son.prototype.getName=function(){alert(this.name)};
复制代码
function Son(){
Father.call(this,arguments)
}
复制代码
function Father(){
this.name ="ss";
this.friends=[1,2,3,4]
}
function Son(){
Father.call(this);
}
Son.prototype = new Father(); // Son 原型得到Father上的属性,name和friends
var son1 = new Son(); // 此时调用Son构造函数为son1 实例上添加了属性(name和friends), 这些属性就屏蔽了原型中的同名属性;
// 调用两次Father构造函数的结果就是有两组属性,一组在实例上,一组在原型上;
复制代码
function object(o){
function F(){};
F.prototype = o;
return new F();
}
// 和 Object.creat() 传递一个参数时候相同
复制代码
function creat(origin){
var clone = object(origin); // 能够是任何返回新对象的函数
clone.sayName(){alert("name")}; //这里的函数每次都建立,不存在复用一说,
return clone;
}
复制代码
function inherit(son,father){
var prototype = object(father.prototype);
// 上句话,建立父类原型的副本,prototype.__proto__ = Father.prototype;
// prototype 继承constructor prototype.constructor 取的是原型链上,原型的Father.prototype.constructor, 为 Father();即:prototype.constructor == prototype.__proto__.constructor // true
// prototype.hasOwnPrototyoe("constructor") //false
prototype.constructor = son; // 弥补重写原型形成的默认属性的修改;
//此时是给prototype 添加了constructor 属性,赋值为son, 屏蔽了原型上的constructor属性
// prototype.hasOwnPrototype("constructor") // true
// prototype.constructor = son;
// prototype.__proto__.constructor = father
son.prototype = prototype;
// 给子类原型赋值为父类原型的副本;
}
//使用:
function Father(){
this.name="11";
this.age=12;
}
Father.prototype.sayName=function(){
alert(this.name);
}
function Son(){
Father.call(this);
this.age=23;
}
inherit(Son,Father);
Son.prototype.sayAge=function(){
alert(this.age)
}
复制代码