就是人们要研究的任何事物,不仅能表示具体事物,还能表示抽象的规则,计划或事件。
属性的无序集合,每个属性可以存一个值(原始值,对象,函数)
对象的特性:封装,尽可能的隐藏对象的部分细节,使其受到保护。只保留有限的接口和外部发生联系。
js 中{},[] 来定义数组和对象
1.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数。
2.[ ]中括号,表示一个数组,也可以理解为一个数组对象。
3.{ } 和[ ] 一起使用,我们前面说到,{ } 是一个对象,[ ] 是一个数组,我们可以组成一个对象数组
调用起来对象的属性用.(点)叠加/对象名['属性名称'],数组用 [下标] 来访问。
二、Js自定义对象的2种方式
1、对象初始化器构造对象
var marry={ name:"marry", age:2, shout:function(){ alert("我是:"+this.name+",今年:"+this.age); }, action:function(){ alert("会吃"); } }; alert(marry.name); alert(marry.age); marry.shout(); marry.action();
2.定义对象的内存分别
当我们创建一个对象 ren,会在栈内存中保存一个地址,栈为长度不可变的地址。
而栈中的地址就对应堆中的存储地址。堆中的存储地址,只要实例化会在堆中开辟一块空间,地址就是栈的地址,内容就是实例化对象里面的内容,如name,sex,eat。可以通过地址引用,访问里面的属性和方法。
当我们再实例化一个对象,又会保存另一个地址及开辟一块空间。
代码段,共同的属性或方法放在代码段中,不在堆中。只执行一次,节省内存空间。代码段会一直存在内存的空间中,知道浏览器关闭。使用prototype方法创建
var ren ={}; ren.name="张三"; ren.sex="男"; ren.eat=function () { alert("吃饭"); } alert(ren.name); alert(ren["name"]);
3.工厂模式
工厂模式虽然解决多次创建相似对象的重复性问题,但是并没有解决对象识别问题,也就是typeof之后他都显示object,具体的对象是什么并没有显示。
function createPerson(name,age,job) { var o=new Object(); o.name=name; o.age=age; o.job=job; o.sayName=function(){ alert(this.name);//this指的是o } return o; } var person1=createPerson("Tom",23,"厨师"); person1.sayName();
4、构造函数方式
构造函数模式和工厂模式的区别
1.没有显式的创建对象。
2.将属性和方法赋给了this对象。
3.没有return语句。
4.函数名第一个字母大写。
构造函数模式优于工厂模式的原因就是,构造函数模式中的对象实例(person1)通过constructor属性或instanceof操作符可以验证person1既是Object的实例,也是Person的实例,同时也证明所有对象均来自于Object。
function Person(name,age,job) { this.name=name; this.age=age; this.job=job; this.sayName=function(){ alert(this.name);//this是Person } } var person1=new Person("Tom",23,"厨师"); person1.sayName();
function Dog(name,age){ this.name=name; this.age=age; this.shout=function(){ alert("我是:"+this.name+",今年:"+this.age); }; this.action=function(){ alert("会吃"); }; } var jack=new Dog("jack",1); alert(jack.name); alert(jack.age); jack.shout(); jack.action();
5.全局作用域
但是构造函数也有缺点,对象是引用类型,对象实例化不是指针的改变,而是简单的复制,复制对象的方法和属性,假设一个对象有上千个实例,它就会复制上千个功能相同的方法,这显然是不可取的。
我们也可以把sayName()函数的定义战役到构造函数的外部,这样我们就将sayName属性设置成等于全局的sayName函数,这样实例化对象就共享全局作用域中的同一个sayName(),解决了构造函数对象方法的多次创建问题。但是全局作用域定义的sayName()函数只能被某个对象调用谈什么全局作用域,而且如果构造函数对象的方法有很多,就需要定义很多全局函数,封装性又从何谈起,于是原型模式应运而生。
function Person(name,age,job) { this.name=name; this.age=age; this.job=job; this.sayName=sayName; } function sayName(){ alert(this.name) } var person1=new Person("Tom",23,"厨师"); person1.sayName();
6.构造函数创建对象
定义对象模拟数组,arguments为js内置的对象。
function myArray () { var lengs= arguments.length; for (var i=0; i<lengs; i++) { this[i]=arguments[i]; } } var arr=new myArray(1,2,3); alert(arr[0]);
7.js动态构造对象
<script type="text/javascript"> /* function speak(something){ alert(something); } */ /* var p=new Object(); p.name="Jack"; // 动态的添加属性 p.func=speak; // 动态的添加方法 alert(p.name); p.func("Hello,Hello,大家好!"); */ /* delete p.name; //删除属性 输出undefine alert(p.name); delete p.func; p.func("Hello,Hello,大家好!"); */ /* p.name=undefined; p.func=undefined; alert(p.name); p.func("Hello,Hello,大家好!"); */ function person(name,age){//构造方法 this.name2=name;//给当前对象动态添加属性 this.age2=age; function speak(something){ alert(something); } this.func=speak; } var p1=new person("Jack",12); alert(p1.name2); p1.func("Hello,EveryOne!"); </script>
三、原型模式创建对象