前端学习指南第三天:对象

对象是一种复合型的值,也可以说是属性的无序集合。javascript对象还可以从一个称为原型(prototype)的对象继承属性。对象的方法通常是继承的属性。
js的对象是动态的,对象的常见方法有创建(create),设置(set),查找(query),删除(delete),检测(test),枚举(enumerate)。
在ECMAscript5中可以对属性的可枚举(for/in遍历),可配置(删除属性等),可写(设置属性值)加以配置。
对象除了属性,还有三个对象特性:
对象的原型 指向另一个对象,本对象的属性继承自他的原型对象
对象的类 是一个标识对象类型的字符串
对象的扩展标记 指明了是否能向该对象添加属性

1.创建对象
1.1对象直接量
var empty={};
var point ={x:1,y:2};
var book ={
author:{
name:“李磊”
}
"main title":“lilei”
}

1.2 通过new创建对象
var o =new object()
1.3 原型
每一个javascript对象都和另外一个对象关联(除了null)。“另一个”对象就是我们熟知的原型,每一个对象都从原型继承属性。
原型对象其实就是普通对象(Function.prototype除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:

 function f1(){};
 console.log(f1.prototype) //f1{}
 console.log(typeof f1. prototype) //Object
 console.log(typeof Function.prototype) // Function,这个特殊
 console.log(typeof Object.prototype) // Object
 console.log(typeof Function.prototype.prototype) //undefined

从这句console.log(f1.prototype) //f1 {} 的输出就结果可以看出,f1.prototype就是f1的一个实例对象。就是在f1创建的时候,创建了一个它的实例对象并赋值给它的prototype,基本过程如下:

var temp = new f1(); f1. prototype = temp;

所以,Function.prototype为什么是函数对象就迎刃而解了,上文提到凡是new Function ()产生的对象都是函数对象,所以temp1是函数对象。

var temp1 = new Function ();
 Function.prototype = temp1;

看了这么多,原型函数到底有啥用,其实很简单,给person.prototype设置了属性或者方法,比如person.prototype.name=lilei,那么在之后的使用过程中,person继承person.prototype的属性,person自带name=lilei的属性。

1.4 Object.create()
创建新对象,第一个参数是这个对象的原型,第二个参数是可选项,用以对象属性进一步描述
Object.create( x:1);
也可以传入null来创建一个没有原型的对象,但不继承任何东西。
Object.create(null)
创建一个普通的空对象
Object.create(Object.prototype)

2 属性的查询和设置

var author = book.author;//查询book的author属性
var author =book["main title'];//查询book的main title属性
book.author=lilei;//设置book的author是lilei
book["main title']=lilei;//设置book的main title是lilei

2.1作为关联数组的对象
book["main title']=lilei;
main title是字符串,所以可以在程序运行时对属性进行删除或者修改

function addstock(portfolio ,stockname, share){
    portfolio[stockname]=share;
}

用户在程序运行时输入stockname,因此在这之前不知道stockname是什么。由于写程序时不知道属性是什么所以不能采取“.”的方式访问portfolio属性,但可以使用[],因为使用的字符串,字符串是动态的,可以删除修改操作。

2.2继承

原型继承
我觉得要正真理解原型链就需要先理解原型继承的原理,理解了如何继承,基本上你就对原型链掌握很深了。我们来实现一个简单的原型继承,我通过阮老师的文章中写的直接继承prototype来实现继承,修改上面的代码:

var Cat = function(){
    this.Color = "black";
    this.Eat = function(){
        alert("吃老鼠");
    };
}
Cat.prototype.A = function(){
    alert("Cat A");
};
Cat.prototype.B = function(){
    alert("Cat B");
};
var Dog = function(){
    this.Weight = "30";
}
Dog.prototype = Cat.prototype;
console.log(Dog.prototype.constructor == Cat); // true
var dog1 = new Dog();
dog1.A(); // Cat A
dog1.B(); // Cat B

上面的代码,我设置了一个Dog来继承Cat,我们使用prototype来实现继承,实际继承成功了,Dog的实例dog1调用了Cat里面的prototype的A和B方法。但是这里出了一个小问题,通过prototype继承导致了Dog的构造函数发生了改变,导致它指向了Cat,这就是我们代码中console输出的原因。我们上面说过每个原型都有一个自己的独立的构造函数,我们却改变了它,这样会导致原型混乱,所以我们必须把Dog的构造函数指回Dog本身。所以修改下代码:

var Cat = function(){
    this.Color = "black";
    this.Eat = function(){
        alert("吃老鼠");
    };
}
Cat.prototype.A = function(){
    alert("Cat A");
};
Cat.prototype.B = function(){
    alert("Cat B");
};
var Dog = function(){
    this.Weight = "30";
}
Dog.prototype = Cat.prototype;
Dog.prototype.constructor = Dog;
console.log(Dog.prototype.constructor == Cat); // false
console.log(Cat.prototype.constructor == Dog); // true
var dog1 = new Dog();
dog1.A(); // Cat A
dog1.B(); // Cat B

上面我通过Dog.prototype.constructor = Dog;这句话把Dog构造函数指回自己了,但是坑爹的是这样做之后,原先的Cat的构造函数也被改变成了Dog,唉,这是要闹哪样,完全坑爹,所以这种继承方式也是失败的,但是我们已经接近成功了,阮老师后面提出了利用空对象作为中介来继承。好的的直接上代码:

var Cat = function(){
    this.Color = "black";
    this.Eat = function(){
        alert("吃老鼠");
    };
}
Cat.prototype.A = function(){
    alert("Cat A");
};
Cat.prototype.B = function(){
    alert("Cat B");
};
var Dog = function(){
    this.Weight = "30";
}
var Fn = function(){};
Fn.prototype = Cat.prototype;
Dog.prototype = new Fn();
Dog.prototype.constructor = Dog;
console.log(Dog.prototype.constructor == Dog); // true
console.log(Cat.prototype.constructor == Cat); // true
var dog1 = new Dog();
dog1.A(); // Cat A
dog1.B(); // Cat B

这下实现完美的继承了,上面是我根据阮老师的提供的方式实现的一个继承,Dog不止继承了Cat里面的prototype的方法,而且构造函数还是指回自己,Cat的构造函数也没被篡改。貌似非常完美的继承。

3.删除属性
delete可以删除对象的属性

delete book.author //book不再有属性author

4.检测属性
in运算符,可以区分不存在的属性和存在但值为undefined的属性

var o={x:1}
"x" in o ;// true
''y'' in o;//false

对象的hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性,对于继承性属性,他将返回false

var o={x:1};
o.hasOwnProperty("x");//true
hasOwnProperty(''y''); //false
hasOwnProperty(''toString''); //false:to string是继承的属性

propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到是自有属性且这个属性的可枚举性为true时才返回true.

var o =inherit({ y:2});
o.x=1;
o.propertyIsEnumerable("x");//true:o 有一个可枚举的自有属性x
o.propertyIsEnumerable("y");//false :y是继承而来的
Object.prototype.propertyIsEnumerable("toString"); //false 不可枚举

“!==”来判断属性是否是undefined

var o={x:1}
"x" !==undefined ;// true o 中有x属性
''y''!== undefined//false o 中没有y属性

5.枚举属性
for/in可以枚举对象的属性,但是Object.prototype的属性有时候并不想被遍历,而在ECMAScript5中是会被枚举的,所以可以用下面的方法

for (p in o){
  if (!o.hasOwnProperty(p)) continue; //跳过属性
}

for (p in o){
  if (type of o[p]=== "function") continue; //跳过方法
}

6.属性getter和setter
属性由名字 值和一组特性(attribute)构成,属性也可以由一个或两个方法代替。(getter 和setter),由这两个方法定义的属性称作“存取器属性”。

 var obj = {

            val:100,
            get getval(){
                return this.val;
            },
            set setval(x){
                this.val = x;
            }
        }

        console.log(obj.getval); //100
        obj.setval = 101;
        console.log(obj.getval); //101

        //demo2
        
        var obj2 = {

            val:200
        }

        obj2.__defineGetter__('name',function(){return this.val});
        obj2.__defineSetter__('name',function(name){this.val = name;})

        console.log(obj2.name) //200
        obj2.name = 201;
        console.log(obj2.name); //201

7.属性的特性

数据属性的特性:值(value),可写性(writable),可枚举性(enumerable),可配置性(configurable)
存取器属性的特性:读取(get),写入(set),可枚举,可配置

8.对象的三个属性:
原型的属性:用以继承属性。详细上文有讲解
类属性:对象的类型信息
可扩展性:是否可以增加属性

9.序列化对象
对象序列化是指将对象的状态转换为字符串,也可以将字符串还原为对象

o ={x:1,y:{z:[false,null,""]}}
s =JSON.stringify(o);//s是'{“x”:1,"y” :{"z":[false,null,""]}}'
p=JSONparse(s); //p是o的深拷贝

10.对象方法
Object.toString()

toString()

toLocaleString()

toJSON()

valueOf()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 第六章:对象 2017.02.24 对象 对象是JavaScript的基本数据类型。对象是一种复合值。对象可以看做...
    静候那一米阳光阅读 341评论 0 1
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,403评论 3 12
  • 2017年5月7日,晴 今天早早的起床收拾好,与你相遇在大楼下会面,一起骑着单车,看电影《摔跤吧,爸爸》,你很爱说...
    i学思阅读 410评论 0 0
  • 其实我觉得微博最适合我这种人碎碎念了因为你要是烦刷屏就不会玩微博了对吧 然后就是其实我想说几个事 第一就是刚我妈跑...
    super西早阅读 169评论 0 0
  • 先说我的一个闺蜜M,从初中认识至今十年。 我、M、D、X四个人一直一起成长,女人真的是很奇怪的生物,明明玩的都很要...
    文小盲阅读 362评论 0 0