摘要:表示对象的父对象,直接继承的对象。的目的是让函数隐式的使用对象。内置的构造函数在中,有几个内置的构造函数,可以直接拿来使用。如果返回的是一个对象,那么返回值为这个对象。
对象的基础 对象的定义
对象是一组由若干个无序的键值对(key/value)组成的数据集合 ,在 javascript 中所有的数据都可以被视作对象。每一个键值对又可以叫做“成员(members)”。
对象(object)的创建(3种方式)对象字面量(对象初始化器)
构造函数
Object.create() es5的创建对象的方式,可以指定原型对象
//方式1 var me = { name: "qingzhui", age: 25 }; //方式2 var me = new Object(); me.name = "qingzhui"; me.age = 25; //方式3 var me = Object.create(Object.prototype, { name: { value: "qingzhui", enumerable: true, wriable: true, configurable: true }, age: { value: 25, enumerable: true, wriable: true, configurable: true } });键名(key),成员的名称
键名,键值对中的 key,我们可以将之称为成员的名称。对象中所有的键名都是字符串,所有加不加引号都可以。必须要加引号的情况:如果_键名不是数字,又不符合标识符的条件_,就必须加上引号。
var obj = { 1: "name", // 数字可以不加引号 "2name": "name2" // 不符合条件的,必须加引号 };键名(key),属性
键名,又可以称作属性(property)。它的键值_可以是任何数据类型,_如果它的值是一个函数的话,我们可以把这个属性叫做方法(method)。
属性的分类属性有两种类型:数据属性(data property)、访问属性(accessor property)。
数据属性(data property)除开访问属性(get/set)之外,都是数据属性。
访问属性(accessor property)访问属性又叫 geter/seter 属性。它只有2种 getter property / setter property。
getter property 当访问一个对象属性时,会隐式的调用一个函数,返回一个生成值。
setter property 当赋值一个对象属性时,会隐式的调用一个函数,返回一个生成值。
var me = { name: "qingzhui", _age: 26, get age(){ return "您真的年龄是:" + _age; }, // 语法 get property_name(){ statement } set age(num){ return _age = num + 2; } // 语法 property_name(parameter_name) { statement } }; me.age = 28; console.log(me.age); // "您真的年龄是:30"
根据属性的所属,可以把属性分为两种自身属性(own property)、继承属性(inherited property)。
自身属性(own property)就是在对象自身定义的属性,我们称之为自身属性。
继承属性(inherited property)通过原型链(prototype chain),继承自父对象、或是祖先对象的属性,我们称之为继承属性。
属性的特性(property attribute)属性的特性,用来描述属性的相关信息。在数据属性中,属性拥有4(_writable、enumerable、configurable、value_)种特性,用来表示这个属性的相关信息。在访问属性中,get 属性拥有3(_get、enumerable、configurable_)种特性,set属性拥有3(_set、enumerable、configurable_)种特性。
value属性的属性值。
wriabletrue 或者 false,表示这个属性_是否可以设置_。
enumerabletrue 或者 false, 表示这个属性_是否可以在循环属性中被枚举_。
var me = { name: "qingzhui", }; console.log(me.propertyIsEnumerable("name")); // trueconfigurable
true 或者 false,表示这个属性是否_可以被删除或者属性值是否可以改变_。
Object.getOwnPropertyDescriptor(obj, "prop")var o1 = Object.create(Object.prototype, { "name": { value: "qingzhui" } }); var o2 = { name: "qingzhui" }; console.log(Object.getOwnPropertyDescriptor(o1, "name")); //{configurable: false,enumerable: false,value: "qingzhui",writable: false} console.log(Object.getOwnPropertyDescriptor(o2, "name")); //{configurable: true, enumerable: true, value: "qingzhui", writable: true}与属性特性相关的方法
Object.defineProperty(obj, "prop", descriptor) 定义或修改一个属性
Object.defineProperties(obj, props) 定义或修改多个属性
Object.create(proto, properiesObject ) 创建一个新的对象
对象的内部属性(internal slots)对象的内部属性只是用来描述对象的相关信息、不属于对象的真正的属性,不可以访问。你可以把它当做特殊的隐藏属性。
[[]prototype]] obejct 表示对象的父对象,直接继承的对象。
[[extensible]] boolean 表示是否可以添加属性
[[class]] string 表示对象的分类
属性的操作 读取属性(read property)读取属性有两种方法,一种是点运算符,一种是方括号运算符。
var me = { name: "qingzhui"; }; //方式1 console.log(me.name); // "qingzhui" //方式2 console.log(me["name"]); // "qingzhui" console.log(me.age); // 读取一个不存在的属性返回 "undefined" console.log(me.toSting) // 读取自身没有的属性,会在原型链上找到最近的返回
需要注意的是,_点运算符与方括号的不同点_:
方括号运算符可以使用表达式。
方括号可以读取键名为数字、不符合标识符条件的、关键字和保留字的属性。
读取一个不存在的属性,返回的是 undefined 。可以利用这一点用来判断变量是否声明。
if(a in window){ // a 声明过 }else{ // a 未声明 }添加属性(add property)
点运算符和方括号运算符不仅可以读取属性,还可以对属性进行赋值。
var me = { name: "qingzhui" }; me.age = 26; // 使用点运算符添加 age 属性 me["like"] = "music"; // 使用方括号运算符添加 like 属性
Object.defineProperty() ES5 的方法,用来新增或者修改一个已经存在的属性。
var me = { name: "qingzhui" }; Object.defineProperty(me, "age", { value: 26, writable: true, // 不定义,默认 false enumerable: true, // 不定义,默认 false configurable: true // 不定义,默认 false });
Object.defineProperties() ES5的方法,用来新增或者修改多个自有属性,并返回该对象。
var me = { name: "qingzhui" }; Object.defineProperties(me, { "age": { value: 26 }, "sex": { value: "boy", wriable: false, enumerable: true, configurable: false } });修改属性(modify property)
var me = { name: "qingzhui" }; me.name = "scl"; // 可以使用点运算符 对 name 属性重新赋值,达到修改的目的删除属性(delete property)
使用 [delete](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/delete) 运算符,可以删除对象的属性,在严格模式下,删除一个不可配置的属性(non-configurable),会抛出异常,在非严格模式下,返回 false,其它情况都返回 true 。
var me = { name: "qingzhui" }; delete me.name; // true遍历对象的属性 for-in
可以使用 in 运算符,来判断某个属性是否在指定的对象中。用[for-in](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in),以任意序迭代一个对象的可枚举属性。每个不同的属性,语句都会被执行一次。
//创建 person 对象 var person = { species: "动物", sex: "男" }; //创建 me 对象,让其 继承 person var me = Object.create(person, { name: { value: "qingzhui", wriable: true, enumerable: true, // 设置可枚举 configurable: true }, age: { value: 26, wriable: true, enumerable: false, // 设置不可枚举 configurable: true } }); var arr = []; for(var a in me){ arr.push(a); } console.log(arr); // ["name", "species", "sex"]
遍历的是对象所有_可遍历(enumberable)的属性_,会跳过不可遍历的属性
它不仅遍历对象自身的属性,_还遍历继承的属性_
Object.keys() es5方法使用 Object.keys(obj) 可以遍历_自身所有可以枚举的属性_,返回所有可枚举自身属性的属性名组成的数组。
console.log(Object.keys(me)); // ["name"]Object.getOwnPropertyNames(obj) ES5方法
使用 Object.getOwnPropertyNames(obj) 可以遍历_自身所有的属性_,返回所有自身属性的属性名组成的数组。
console.log(Object.getOwnPropertyNames(me)); // ["name", "age"]检查属性是否存在
hasOwnProperty() 如果自身含有这个属性,返回 true,否则 false。
var me = { name: "qingzhui" }; console.log(me.hasOwnProperty("name")); // true console.log(me.hasOwnProperty("age")); // fasle
in 运算符,用来判断自身或者继承来的属性是否在这个对象中。
var person = { species: "动物", sex: "男" } var me = Object.create(person); me.name = "qingzhui"; console.log("name" in me); // 检查自身的属性 true console.log("sex" in me); // 检查继承的属性 true console.log("job" in me); // 检查没有的属性 fasle对象的引用
对象的引用是按址引用的,如果不同的变量引用同一个对象,它们会指向_同一个内存地址_,修改 其中一个变量,会影响到其它的变量。
var me = { name: "qingzhui" }; var qingzhui = me; // 让 qingzhui 引用 me 对象 qingzhui.name = "scl"; // 修改 qingzhui 的 name 属性 console.log(me.name); // "scl" 改变了 me 的 name 属性对象的分类
标准对象(standard object)
如 Object、Aaary等
宿主对象(hosted object)
如DOM中的 document,BOM中的 window ,nodejs中的 http 。
自定义对象(user-define object)
如 var o = {};
对象深入 原型和继承 原型(prototype)在 javascript 中,每一个对象都有一个内部的相关信息叫 prototype ,可以用 [[prototype]]表示。
[[prototype]]的值是一个对象或者是 null ,我们把这个对象称之为原型对象,或者说是父对象。
继承(inheritance)在 javascript 中,查找属性的时候,先从自身查找,如果找不到,就在其父对象,一直往上找,直到 null,这种机制就叫做继承。
原型链(prototype chain)一个对象的父对象,父对象的父对象,形成一个链,称之为原型链(prototype chain)。
不是所有的对象都有父对象,Object.prototype 是所有对象的根,它的原型对象(父对象)是 null。
查找对象的原型对象(父对象) __proto__返回对象的原型对象(父对象),在 ES6 之前,只有部分浏览器支持,在ES6 被正式纳入标准。
_proto 和 [[prototype]] 指向同一个对象,即它的原型对象(父对象)。
funtion Person(){ // } var me = new Person(); console.log(me.__proto__ === Person.prototype); // truegetPrototypeOf()
返回指定对象的原型对象。
Object.getPrototypeOf(object)isPrototypeOf()
测试一个对象是否存在于另一个对象的原型链上。
obj.prototype.isPrototypeOf(object)资源
从本质认识JavaScript的原型继承和类继承
Javascript面向对象编程(三):非构造函数的继承
定义对象的父对象使用 Object.create(myparent, )
定义一个没有 return 的构造函数 F,然后 F.prototype = myparent,使用 new F()
限制对象的一些方法Object.isExtensible() // 判断是否可扩展 Object.preventExtensions() Object.isSeal() // 判断是否密封 Object.seal() Object.isFrozen() // 判断是否冻结 Object.freeze()确定对象的子类型
Object.prototype.toString.call(myObj); console.log(Object.prototype.toString.call({})) // "[object Object]"复制对象
方法一(深拷贝)
Json.parse(Json.stringify(obj));
方法二 (es6)
Object.assign(target, ...sources)
javascript中的深拷贝和浅拷贝?
深入剖析 JavaScript 的深复制
判断对象是否相等function is_obj_equal(obj1, obj2){ var keys1 = Object.keys(obj1).sort(); var keys2 = Object.keys(obj2).sort(); if(keys1.length !== keys2.length){ return false; } if (!keys1.every(function(k, i){ return (k === keys2[i]); })){ return false; } return keys1.every(function(kk) { var v1 = obj1[kk]; var v2 = obj2[kk]; if ( Array.isArray(v1) ) { return is_array_equal(v1,v2); } else if ( typeof v1 === "object" && v1 !== null) { return is_obj_equal(v1,v2); } else { return v1 === v2; } }); }面向对象编程 this
在 javascript 中,当一个函数被调用时,它有一个相关值被称之为 ‘ ThisBinding ’。
在函数定义时,‘ ThisBinding ’ 是用 this 表示。
‘ ThisBinding’ 的目的是让函数隐式的使用对象。
this 的值是什么?当一个函数被当做一个对象的方法调用时,this 的值是指调用这个函数的对象。
var f = function(){ return this; }; var o = { f1: f}; // this 是 o console.log(o == o.f1()); // true
当一个函数,使用 new 调用, this 的值是这个新创建的对象。
var F = function(){ this.name = "qingzhui"; }; var me = new F(); // this 是 me console.log(me); // { name: "qingzhui"}
当一个函数,是在全局上下文直接调用,如果是严格模式,this 的值是 undefined 。非严格模式下是全局对象(如 window)。
"use strict" var f = function(){ return this; }; console.log(f()); // this 是 undefined
当一个函数是在一个函数里面,函数被调用时,如果是严格模式,this 的值是 undefined ,否则是全局对象
"use stric" var f = function(){ var h = function(){ return this; // this 是 undefined }; return h(); }; console.log(f() === undefined); // true var o = { p = function(){ var f = function(){ return this; // this 是 undefined }; return f(); } }; console.log(o.p() === undefined); // true资源
js 中 this 关键字详解
详解this
构造函数(constructor)当一个函数被设计使用 new 调用的时候,我们叫这个函数为构造函数。构造函数是用来创建函数的一种方式。
内置的构造函数在 JavaScript 中,有几个内置的构造函数,可以直接拿来使用。
var o = new Object(); var arr = new Array(); var fun = new Function(); var date = new Date(); var reg = new Regex();原始类型值的包装器
var str = new String("a"); var num = new Number(1); var boolean = new Boolean(true);
构造函数应该已大写字母开始。
原型属性(prototype)在 JavaScript 中,每一个函数有一个特殊的属性 prototype 。
var f = function(){ }; console.log(f.hasOwnProperty("prototype")); // true console.log(Object.hasOwnProperty("prototype")); // true console.log(Array.hasOwnProperty("prototype")); // true
用户自定义的函数,它的原型属性的值默认值:{ constructor: f}
var f = function(){ }; console.log(f.hasOwnProperty("prototype")); // true console.log(Object.getOwnpropertyNames(f.prototype).lenght === 1); // true console.log(Object.getOwnpropertyNames(f.prototype)[0] === constructor); // true console.log(Object.getOwnPropertyDescriptor(f.protptype, "constructor")); // { value: f, writable: true, enumerable: false, configurable: true}
内置的函数,它的原型属性的默认值是
Object.prototype 就是 Object.prototype, Object.prototype 被设计为 new Object()新对象的父对象
在严格模式下,内置的构造函数的原型属性不能被改变,否则会报错。
操作符 new操作符 new 是用来和函数一起,创建一个对象。
// 语法 new function_name(args);new 是如何工作的?
每一个函数都有一个属性叫做原型属性(prototype)
它的值默认是{ constructor: F}
创建一个新的空对象,将它的父对象设置为 F.prototype
执行构造函数,把 this 指向这个新对象
如果构造函数没有返回值,或者返回的不是一个对象,那么 新对象 将作为返回值。如果返回的是一个对象,那么返回值为这个对象。
var F1 = function(){ this.name = 1; }; var F2 = function(){ this.name = 2; return 3; }; var F3 = function(){ this.name = 3; return { name: "qingzhui" }; }; var f1 = new F1(); // { name: 1} var f2 = new F2(); // { name: 2} var f3 = new F3(); // { name: "qingzhui"}使用 new 创建的对象的父对象是什么?
如果构造函数F返回的不是一个对象,或者没有返回值,那么它的父对象只指 F.prototype
如果构造函数F有返回语句,返回一个对象,要看返回的对象是怎么创建的。来判断它的父对象。
继承全面理解面向对象的 JavaScript
文章同时发表在:
http://blog.qingzhui.net/post...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/91623.html
摘要:如果没有学习过计算机科学的程序员,当我们在处理一些问题时,比较熟悉的数据结构就是数组,数组无疑是一个很好的选择。 showImg(https://segmentfault.com/img/bVTSjt?w=400&h=300); 1、常见 CSS 布局方式详见: 一些常见的 CSS 布局方式梳理,涉及 Flex 布局、Grid 布局、圣杯布局、双飞翼布局等。http://cherryb...
摘要:如果没有学习过计算机科学的程序员,当我们在处理一些问题时,比较熟悉的数据结构就是数组,数组无疑是一个很好的选择。 showImg(https://segmentfault.com/img/bVTSjt?w=400&h=300); 1、常见 CSS 布局方式详见: 一些常见的 CSS 布局方式梳理,涉及 Flex 布局、Grid 布局、圣杯布局、双飞翼布局等。http://cherryb...
阅读 3327·2023-04-26 00:07
阅读 3921·2021-11-23 10:08
阅读 2939·2021-11-22 09:34
阅读 858·2021-09-22 15:27
阅读 1748·2019-08-30 15:54
阅读 3742·2019-08-30 14:07
阅读 912·2019-08-30 11:12
阅读 677·2019-08-29 18:44