Javascript中的对象和原型

本文深入探讨了JavaScript中对象和原型的工作原理,介绍了对象的创建方法及其操作,并详细解析了构造函数、原型对象等概念,帮助开发者更好地理解和利用这些特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
Javascript是一种基于对象的语言,但是它又不是一种真正的面向对象编程语言,因为它的语法中没有类这一概念。要了解javascript中的基于对象原理,需要了解的javascript中的对象和原型。这篇文章就带大家逐一了解,看完之后你会发现深入了解这一原理的重要性,在开发过程中节省时间和空间。

对象

ECMA-262将对象(object)定义为”属性的无序集合,每个属性存放一个原始值、对象或函数”(unordered collection of properties each of which contains a primitive value, object, or function)。这意味着对象是无特定顺序的值的数组。说的通俗一些,对象其实就是一种引用类型,在javascript中引用类型是一种数据结构,将数据和功能组织在一起。

1. 对象的创建的基本方法

使用new运算符

<script>
    var user = new Object();              //使用new运算符创建一个对象
        user.name = 'java-tree';        //给对象添加属性
        user.age = 1;
        user.address = '湖北武汉';
        alert(user.name + " " +user.address);//返回 'java-tree 湖北武汉'
</script>

JSON法创建

var user = {
        name:'java-tree',
        age:1,
        address:'湖北武汉'    
};
alert(user.name + " " +user.address);//返回 'java-tree 湖北武汉'
u 传统赋值
var user = {};
user.name = 'java-tree';        //给对象添加属性
user.age = 1;
user.address = '湖北武汉';
alert(user.name + " " +user.address);//返回 'java-tree 湖北武汉'

2. 基于对象的操作

属性的调用
上述对象创建中已经使用了属性调用的一种方式,即’.’运算符,方法如下:

alert(user.name + " " +user.address);//返回 'java-tree 湖北武汉'

另一种方法:

alert(user['name'] + " " +user['address']);//返回 'java-tree 湖北武汉

给对象添加方法(直接内部增加和外部调用)

var user = {
    name:'java-tree',        //给对象添加属性
    age:1,
    address:'湖北武汉',
    showInfo:function(){//添加一个方法
alert(this.name+" "+this.age+" "+this.address);//返回 'java-tree 1湖北武汉'    
    },
    showHello:showHello//将对象外部的方法添加到对象
};
function showHello(){
    alert("Hello!");    
}

删除对象属性

var user = {
    name:'java-tree',  
    age:1,
    address:'湖北武汉'
};
alert(user.name);//返回‘java-tree’
delete user.name;//删除user的name属性
alert(user.name);//返回‘undefined’

对象的创建的常用方法
前面我们也有介绍对象的基本的创建方法,之所以称之为基本的创建方法,是因为这种方法虽然直观,但是如果需要我们创建多个引用类型相同的对象,那么就需要写很多重复的代码,这在实际开发过程中是不合适的,大大增加了代码量。下面介绍工厂模式和构造函数的方法。
工厂模式

function create(name, age) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.run = function () {
    return this.name +' '+ this.age;
    };
    return obj;
}
var obj1= create('A', 1);    //第一个实例
var obj2= create('B', 2);    //第二个实例
alert(obj1.run());
alert(obj1.run());

工厂模式虽然解决了大量重复代码的问题,但是也存在弊端——在识别实例的时候无法识别具体是哪一个对象创建的。

alert(typeof obj1);          //Object

构造函数

function User(name, age) {
    this.name = name;
    this.age = age;
    this.run = function () {
    return this.name  + ' '+this.age;
    };
}
//创建对象
var user1= new User('A', 1);
var user2= new User('B', 2);
//对象识别
alert(user1 instanceof User);//true 

构造函数的方法解决了重复实例化和对象识别的问题,但是也存在一定的问题,观察如下代码:

alert(user1.run==user2.run);//结果返回的是false

结果返回的是false,这就说明方法其实也是一种引用地址。如果我们同样重复创建了多个对象,那么每个对象中的方法都会在内存中开辟新的空间,这样浪费的空间就比较多。为解决这一问题,下面将引入原型对象的概念。

原型对象

构造函数方法
这里写图片描述
原型对象方法
这里写图片描述
从上述示意图中,可以看出所有User创建出的对象都共享了方法show(),因此“user1.show == user2.show;”在此处返回值为true。

function User(name,age){//构造方法
        this.name = name;//对象属性
        this.age = age;
}
User.prototype.addr = '湖北武汉';//在原型中添加属性
User.prototype.show = function(){//在原型中添加方法
        alert(this.name+'|'+this.age);    
};
var user1 = new User('A',1);//创建实例
var user2 = new User('B',2);
user1.show();//调用show()方法
user2.show();
alert(user1.show == user2.show);//返回 true 说明show方法是共享的

但是存在一个问题,如果既在构造方法中添加了一个属性,又在原型中添加了该属性,还在实例中添加了该属性,那么我们访问的究竟是哪一个属性呢?
此处属性调用的优先级服从就近原则:实例属性>对象属性>原型属性,大家可以自己动手尝试一下。

关于原型对象的创建,还有另外两种方法,一个是动态原型对象的创建方法,再有就是字面方法创建。
动态原型对象

function User(name,age){//构造方法
        this.name = name;//属性
        this.age = age;
        this.addr = '湖北恩施';
        User.prototype.addr = '湖北武汉';//在原型中添加属性
        User.prototype.show = function(){//在原型中添加方法
            alert(this.name+'|'+this.age+'|'+this.addr);    
        };
}
var user1 = new User('ZXC',22);//创建实例
var user2 = new User('CXZ',21);

动态原型对象相比之前的其实没有什么太大的差别,只是将方法和属性封装在一块看起来更加直观。但是如果细心去研究这一段代码的话,也会发现其存在一定的问题,在每次创建对象的时候,都会再创建一次原型,虽然控件没有额外增加,但是时间上确实增加了,因为每次都要重新创建,要解决这个问题只需要增加一个if判断即可:

if(this.show==undefined){//如果run方法还没有被创建
        User.prototype.show = function(){//在原型中添加方法
            alert(this.name+'|'+this.age+'|'+this.addr);    
        };
}

这样就减少了不必要的开销。

字面量方式创建原型

function User(name,age){
        this.name = name;
        this.age = age;
}
User.prototype = {
        addr : '湖北武汉',
        show : function(){
            alert(this.name+'|'+this.age+'|'+this.addr);
        }
};  
//重写了原型
User.prototype = {
        other : '重写原型',
        show : function(){
            alert(this.addr);    
        }
};    

字面量方式需要注意的点在上述代码中已经体现,使用字面量方式创建后,不能再使用字面量的方式重写原型,一旦重写了原型,原来的原型中定义的所有属性和方法都将被清除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值