晓石头的博客
邮箱:178673693@qq.com
转载请注明出处,原文链接:http://blog.youkuaiyun.com/qiulanzhu/article/details/50583684
/*===================对象的创建======================*/
var box = new Object(); //创建对象
box.name = "Qiu"; //添加属性
box.age = 27; //添加属性
box.run = function(){
return this.name + this.age + "运行中<br>";//this指当前作用域下的对象box
};
document.write(box.run());
var name = "jack";
document.write(this.name +"<br>");//这里的this表示window
/*===================相似对象的创建问题======================*/
var box1 = new Object();//创建对象
box1.name = "Qiuyi1"; //添加属性
box1.age = 26; //添加属性
box1.run = function(){
return this.name + this.age + "运行中...<br>";//this指当前作用域下的对象box
};
document.write(box1.run())
var box2 = new Object();//创建对象
box2.name = "Qiuyi2"; //添加属性
box2.age = 27; //添加属性
box2.run = function(){
return this.name + this.age + "运行中<br>";//this指当前作用域下的对象box
};
document.write(box2.run())
var box3 = box2; //创建对象
box3.name = "Qiuyi3"; //添加属性
box2.age = 28; //添加属性
box3.run = function(){
return this.name + this.age + "运行中<br>";//this指当前作用域下的对象box
};
document.write(box3.run());
//利用工厂模式:解决创建对象的重复操作
function createObject(name, age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age + '运行中。。。';
}
return obj;
}
var box4 = createObject('qiu1', 26);
var box5 = createObject('qiu2', 27);
document.write(box4.run() +'<br>');
document.write(box5.run() +'<br>');
function createObject2(name, age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age + '运行中。。。';
}
return obj;
}
var box6 = createObject('qiu3', 28);
document.write(box6.run() +'<br>');
document.write(box4 instanceof Object);
document.write(box5 instanceof Object);//都为true,产生识别问题,容易分不清到底是哪个对象的实例
document.write(box6 instanceof Object);
//构造函数:解决创建对象的重复操作、可识别
//1.构造函数默认生成var obj = new Object();
//2.this就相当于obj
//3.构造函数默认返回对象引用
//注意点:
//构造函数的函数名必须大写
//必须使用new运算符
function Box(name, age){
this.name = name;
this.age = age;
this.run = function(){
return this.name + this.age + '运行中。。。<br>';
}
}
var box7 = new Box('yi1', 26);
var box8 = new Box('yi2', 27);
document.write(box7.run());
document.write(box8.run());
function Desk(name, age){
this.name = name;
this.age = age;
this.run = function(){
return this.name + this.age + 'ok<br>';
}
}
var box9 = new Desk('desk', 3);
document.write(box9.run());
document.write(box7 instanceof Box);
document.write(box8 instanceof Box);
document.write(box9 instanceof Desk);//可识别
//对象的比较
var Desk1 = new Desk('desk', 1);
var Desk2 = new Desk('desk', 1);
document.write(Desk1.name == Desk2.name);
document.write(Desk1.run() == Desk2.run());
document.write(Desk1.run != Desk2.run);//比较的是方法的引用地址
//对象冒充(后面会详细讲)
var obj = new Object();
Box.call(obj, 'Box', 2);
document.write(obj.run());
/*===========================原型==========================*/
function Book(){
this.name = "Book!";
}
Book.prototype.name = 'book'; //原型属性
Book.prototype.age = 1;
Book.prototype.run = function(){ //不同的对象,原型方法地址共享
return this.name + this.age +'运行中...';
}
var book1 = new Book();
var book2 = new Book();
document.write(book1.run == book2.run); //共享原型方法地址
document.write(book1.run());
document.write(book1.prototype);
document.write(book2.__proto__);//[object Object]是一个对象
document.write(book2 +'<br>');
//构造属性:获取构造函数本身
//构造函数对象 对应的 原型对象
document.write(book1.constructor +"<br>");
//优先返回实例属性
var book3 = new Book();
document.write(book3.name +"<br>");
document.write(book3.hasOwnProperty("name") +"<br>");
document.write("name in book3:");
document.write("name" in book3);//判断对象中是否有某一属性,不管是原型中还是实例中
delete book3.name; //删除对象属性
document.write(book3.hasOwnProperty("name") +"<br>");
document.write(book3.name +"<br>");
document.write("name in book3:");
document.write("name" in book3);
//判断是否只是原型中有该属性
function isProperty(obj, property){
return !obj.hasOwnProperty(property) && (property in obj);
}
var win = new Book();
document.write(isProperty(win, "age") +"<br>");
document.write(isProperty(win, "name") +"<br>");
function Flower(){};
//将原型属性和方法封装,这里的{}就是对象,new Obj();就相当于{};
Flower.prototype = {
//constructor : Flower, //强制指向Flower
name : "rose",
age : 1,
run : function(){
return this.name + this.age + "运行中...";
}
}
var flower = new Flower();
document.write(flower.prototype +"<br>");//undefined
document.write(flower.__proto__ +"<br>");//[object Object]
document.write(Flower.prototype +"<br>");//[object Object]
document.write(flower.name +"<br>");
document.write(flower.age +"<br>");
document.write(flower.run() +"<br>");
//字面量创建方式:constructor属性指向Objcet(因为字面量创建时有{},相当于new Obj())
//构造函数创建方式:constructor属性指向类
document.write(flower.constructor +"<br>");//function Object() { [native code] }
//怎么让字面量创建方式也指向实例?
//在字面量创建对象里添加:constructor : Flower,
//重写原型函数,之前的原型属性和方法都会消失
Flower.prototype = {
name : "sun",
}
var sun = new Flower();
document.write(sun.name);
document.write(sun.age +"<br>");
//内置类的原型
//数组排序
var box = [4,3,5,3,6,1,4,9,0];
document.write(box.sort() +"<br>");
//查看Array原型里的方法
document.write(Array.prototype.sort +"<br>");
//查看String原型里的方法
document.write(String.prototype.substring +"<br>");
//新增String原型方法(内置类型的功能扩展)
String.prototype.addString = function(){
return this + ",追加字符串!<br>";
}
document.write("qiuyi".addString());
//原型的缺点
//1.字面量创建不灵活,没有办法通过传参改变属性值
//2.共享导致的问题
//为了解决构造传参和共享问题,采用:构造函数 + 原型模式。
function Fruit(name, weight){
this.name = name;
this.weight = weight;
this.shape = ["方","圆","扁"];
}
Fruit.prototype = {
constructor : Fruit,
run : function(){
return this.name + this.weight;
}
}
var fruit = new Fruit("苹果", 5);
document.write(fruit.run());
//动态原型模式,将原型封装到构造函数类
function Fruit1(name, weight){
this.name = name;
this.weight = weight;
this.shape = ["方","圆","扁"];
if( typeof(this.run) != "function" ){
Fruit1.prototype.run = function(){
return this.name + this.weight;
}
}
}
var fruit1 = new Fruit1("苹果", 5);
document.write(fruit1.run());
//寄生构造函数:构造函数+工程模式。---很通用
function Moon(name, age){ //类名大写
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age;
}
return obj;
}
//稳妥构造函数:构造函数例不能用this,函数外不能用new
function Sum(name, age){ //类名大写
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age;
}
return obj;
}
var isSum = Sum("sun", 1000);
/*============================原型链接继承================================*/
//通过原型链实现
//有个问题:1.无法传参,
function Ball(){
this.name = "qiu";
}
function Basketball(){
this.age = 2;
}
Basketball.prototype = new Ball();//通过原型链继承:超类实例化后的对象,赋值给子类的原型属性
var myBall = new Basketball();
document.write(myBall.name +"<br>");
/*============================对象冒充继承==================================*/
//解决:1.可以传参
//但有一个问题:无法继承基类的原型属性(方法一般放在原型里,多个对象只需要一份。这样对象冒充就无法继承到这个方法了。)
function Good(name, age){
this.name = name;
this.age = age;
}
function Better(name, age){
Good.call(this, name, age);
}
var myState = new Better("yi", 27);
document.write(myState.name +"<br>");
/*==============================原型链+对象冒充=============================*/
//最常用的继承方式
//有个小问题:调用父类两次
function Big(name, age){
this.name = name;
this.age = age;
}
function Bigger(name, age){
Big.call(this, name, age); //对象冒充继承
}
Bigger.prototype = new Big(); //原型链继承
var myBigger = new Bigger("qiuyi", 27);
document.write(myBigger.name);
/*==============================原型式继承:和原型链继承一样,只是变化了结构=================================*/
//存在共享问题,一个对象改了原型属性,所有对象的都变了。
//临时中转函数
function objtest(o){ //o为传入的对象
function Fun(){};
Fun.prototype = o; //将对象o赋值给F的原型对象,等价与Fun.prototype = new Obj();
return new Fun();
}
//字面量的申明方式,类似与var box = new Box();
var myobj = {
name : "qiuyi",
age : 27,
family : ["哥哥", "弟弟", "妹妹"]
}
var firstBox = objtest(myobj);
document.write(firstBox.family);
/*==============================寄生式继承:原型式 + 工厂模式=================================*/
//临时中转函数
function objfirst(o){ //o为传入的对象
function Fun(){};
Fun.prototype = o; //将对象o赋值给F的原型对象,等价与Fun.prototype = new Obj();
return new Fun();
}
//寄生函数
function createfirst(o){
var funcfirst = objfirst(o);
funcfirst.run = function(){
return this.name + "方法";
}
return funcfirst;
}
var myobjfirst = {
name : "qiuyi",
age : 27,
family : ["哥哥", "弟弟", "妹妹"]
}
var first1 = createfirst(myobjfirst);
document.write(first1.run());
/*==============================寄生组合继承=================================*/
//解决原型链+对象冒充的调用基类两次的问题
//临时中转函数
function tmpObj(o){ //o为传入的对象
function Fun(){};
Fun.prototype = o; //将对象o赋值给F的原型对象,等价与Fun.prototype = new Obj();
return new Fun();
}
//寄生函数
function create(Animal, Cat){
var fun = tmpObj(Animal.prototype);
fun.constructor = Cat; //调节构造指针
Cat.prototype = fun;
// Cat.prototype = Animal.prototype; //为什么不直接用这一句呢?
}
function Animal(name, age){
this.name = name;
this.age = 27;
if( typeof(this.run) != "function" ){
Animal.prototype.run = function(){
return this.name + this.age + "running...<br>";
}
}
}
function Cat(name, age){ //对象冒充继承
Animal.call(this, name, age);
}
create(Animal, Cat); //原型式继承
var myCat = new Cat("mao", 5);
document.write(myCat.run());