JavaScript | 对象与属性
————————————————————————————————————————————
对象:JavaScript是基于原型的语言,没有Class,所以将函数作为类
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
面向对象术语
- 对象:属性的无序集合,每个属性存放一个原始值、对象和函数
- 类:每个对象都由类定义,类不仅要定义对象的接口(开发者访问的属性和方法),还要定义对象的内部工作(使属性和方法发挥作用的代码)
- 实例:程序使用类创建对象时,生成的对象叫做类的实例。每个实例的行为相同,但实例处理一组独立的数据。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
四种基本能力
- 封装:把相关的信息(无论数据或方法)存储在对象中的能力
- 聚集:把一个对象存储在另一个对象内的能力
- 继承:由另一个类(或多个类)得来类的属性和方法的能力
- 多态:编写能以多种方法运行的函数或方法的能力
————————————————————————————————————————————
内建对象
- 数据封装对象
- Object对象
- Object对象是Js中所有对象的父级对象,我们创建的所有对象都继承于此
- 方法:
- Object.create():指定原型对象和属性创建一个对象
- Object.defineProperty():给对象添加/修改一个属性并指定该属性的配置
- Object.defineProperties():在一个对象上添加或修改一个或者多个自有属性,并返回该对象
- Object.keys():方法会返回一个由给定对象的所有可枚举自身属性的属性名组成的数组,数组中属性名的排列顺序和使用for-in循环遍历该对象时返回的顺序一致(两者的主要区别是for-in还会遍历除一个对象从其原型链上继承到得可枚举的属性)
- Object.getOwnPropertyNames():返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组
- Object.getOwnPropertyDescriptor():返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性))
- Object.getPrototypeOf():返回指定对象的原型(也就是该对象内部属性[[Prototype]]的值)
- Object.freeze():冻结一个对象。冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说这个对象永远不能改变的
- Object.isFrozen():判断对象是否已经被冻结
- Object.preventExtensions():阻止对象扩展
- Object.isExtensible():检测一个对象是否可扩展(是否可以在它上面添加新的属性)
- Object.seal():可以让一个对象密封,并返回被密封之后的对象。密封对象是指那些不能添加新的属性、不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性,但可能可以修改已有属性的值的对象
- Object.isSealed():检测一个对象是否被密封sealed
var obj = {};
// 检测是否可扩展
console.log(Object.isExtensible(obj));
// 内建对象Date
var oTest = new Date();
console.log(Object.isExtensible(oTest));
oTest.x = 1;
console.log(oTest.x);
// 对象锁定
oTest2 = Object.preventExtensions(oTest);
// 证明oTest2与oTest是同一对象,已经不可扩展
console.log(oTest2 === oTest);
console.log(Object.isExtensible(oTest2));
// 此时显示y为undefined未定义的
oTest2.y = 1;
console.log(oTest2.y);
// defineProperty方法会报错,提示不可扩展
// Object.defineProperty(oTest2,'z',{value:1});
// *******************************************************************
// 封闭对象seal()
var oTest3 = { x: 1, y: 2 };
var oTest4 = Object.seal(oTest3);
// false不可扩展
console.log(Object.isExtensible(oTest3));
// true已经被封闭了
console.log(Object.isSealed(oTest3));
// 自身已有的属性不受影响
oTest3.y = 55;
console.log(oTest3.y);
// 提示不能将新属性定义为访问器属性
// Object.defineProperty(object,'username',{
// get:function(){
// return 'this is a test';
// }
// });
oTest3.z = 111;
console.log(oTest3.z);
// 已有属性也不会被删除
delete oTest3.x;
console.log(oTest3.x);
// 检测属性 configurable:false,不可配置
console.log(Object.getOwnPropertyDescriptor(oTest3, 'x'));
// *******************************************************************
// 冻结对象freeze()
console.log('freeze:');
var oTest5 = { x: 1, y: 2, z: 3 };
oTest6 = Object.freeze(oTest5);
// 冻结后检测对象 writable:false,变成了只读属性
console.log(Object.getOwnPropertyDescriptor(oTest6, 'x'));
// 检测是否已经被冻结
console.log(Object.isFrozen(oTest6));
// *******************************************************************
// 浅冻结
// 在对象中添加子对象,向子对象添加属性
console.log('Shallow frozen:');
var oTest7 = {
internal: {}
};
Object.freeze(oTest7);
oTest7.internal.x = 1;
console.log(oTest7.internal.x);
// 在这里只冻结了oTest7的internal,internal对象没有被冻结
console.log(Object.getOwnPropertyDescriptor(oTest7, 'internal'));
console.log(Object.getOwnPropertyDescriptor(oTest7.internal, 'x'));
// *******************************************************************
// 递归冻结,包括子对象全部冻结
console.log('Deep frozen:'); function deepFreeze(obj) {
var prop, propKey;
Object.freeze(obj);
// 通过for循环来检测是否为子对象,并递归调用
for (propKey in obj) {
prop = obj[propKey];
// 如果这个对象没有私有属性||类型不等于Object||已冻结
// 则跳过 - 进入下一循环
if (!obj.hasOwnProperty(propKey) || !(typeof prop === 'object') || Object.isFrozen(prop)) {
continue;
}
deepFreeze(prop);
}
}
var oTest8 = {
internal: {
x: 1
}
}
deepFreeze(oTest8);
oTest8.internal.y = 2;
console.log(oTest8.internal.y);
console.log(Object.getOwnPropertyDescriptor(oTest8, 'internal'));
console.log(Object.getOwnPropertyDescriptor(oTest8.internal, 'x'));
console.log(Object.getOwnPropertyDescriptor(oTest8.internal, 'y'));
// *******************************************************************
// 冻结规则:
// 1.如果一个对象是可扩展的,那则是非冻结的,
// 2.一个不可扩展的对象同时也是一个冻结的对象
var oTest9 = {};
Object.preventExtensions(oTest9);
console.log(Object.isFrozen(oTest9));
// 3.空对象和非空对象对比,默认都是不被冻结的,可扩展的
var oTest10 = {};
var oTest11 = { x: 1 };
// 4.空对象禁止扩展后,是被冻结的
Object.preventExtensions(oTest10);
console.log('3:' + Object.isFrozen(oTest10));
// 5.非空对象禁止扩展后,不冻结
Object.preventExtensions(oTest11);
console.log('4:' + Object.isFrozen(oTest11));
// 6.非空对象删除已有属性后,冻结
delete oTest11.x;
console.log('5:' + Object.isFrozen(oTest11));
// 7.如果一个不可扩展的对象拥有一个可写但不可配置的属性,非冻结
// 8.如果一个不可扩展的对象拥有一个不可配置但可写的属性,非冻结
// 9.如果一个不可扩展的对象拥有一个访问器属性,非冻结
// 10.被冻结的对象同样也是被密封的和不可扩展的
- Object.prototype
- 属性:Object.prototype.constructor:返回一个指向创建了该对象原型的函数引用
- 方法:
- Object.prototype.isPrototypeOf():检测一个对象是否存在于另一个对象的原型链上
- Object.prototype.propertyIsEnumerable():检测指定的属性名是否是当前对象可枚举的自身属性
- Object.prototype.toString():返回一个代表该对象的字符串
- Object.prototype.valueOf():返回的诗this值,即对象本身
- Number对象
- Boolean对象
- Array对象
- Function对象
- String对象
- 支持正则对象的方法
- search
- match
- replace
- split
var myArr = new Array;
var str = 'this is a test hello ishello maizi';
var patt = /is/ig;
var i = 0;
while ((myArr[i] = patt.exec(str)) !== null)
{
console.log(i + 1 + ':' + myArr[i] + " " + patt.lastIndex);
i++;
} str = 'this is a testis';
patt = /is/ig;
var res = str.match(patt);
console.log(res); res = str.search(patt);
console.log(res); res = str.replace(patt, '!');
console.log(res); // 将年月日替换为月日年
str = '2017-06-04';
res = str.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2-$3-$1');
console.log(res); // 调用方法,将匹配到的内容替换成为hugh+匹配内容大写
str = 'this is a testis';
res = str.replace(/is/g, func); function func(match)
{
return 'hugh' + match.toLocaleUpperCase();
}
console.log(res); // split
// 将匹配到的字符串前后拆分
res = str.split(/\s+/);
console.log(res);
- 工具类对象
- Math对象
- Date对象
// 显示当前时间
console.log(Date());
// 显示毫秒数
var d = new Date(138555555550);
console.log(d);
// 显示填入的时间
var d = new Date(2011, 1, 3);
console.log(d);
// 传入月日
var d = new Date(10,25);
console.log(d);
// Date提供的方法
console.log(Date.now()); // 自1970年至今所经过的毫秒数
console.log(Date.parse("2017-01-01")); // 解析一个字符串,返回所经过的毫秒数
// ... - RegExp对象
// 通过test()方法检索字符串中的内容,返回true或false
var patt1 = new RegExp("r");
var res1 = patt1.test('this is javascript course');
console.log(res1);
// 另一种形式
// 加上i表示忽略大小写
patt2 = /Javascript/i;
res2 = patt2.test('this is javascript course');
console.log(res2);
// 是否包含[]中的字符
res3 = /[abc]/.test('Brlue');
// 加上^表示除了abc之外的
res4 = /[^abc]/.test('Brlue');
// 检测是否包含数字
res5= /[0-9]/.test('999');
// 检测是否包含字母
res5= /[a-z]/.test('999');
// 是否出现了以下几个
res5= /php|javascript|ios/.test('php');
console.log(res3);
console.log(res4);
console.log(res5);
- 错误对象
- Error对象
- 通常使用try/catch/finally来捕获Error错误
- Error类型
- EvalError
- InternalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
try
{
// 当调用不存在的notExists(),e.name和e.message存放的错误名称和错误信息
// notExists();
var n = 0;
if (n == 0)
{
// 手动抛出一个错误信息
throw new Error('Throw an error message');
}
}
catch (e)
{
console.log(e.name);
console.log(e.message);
}
finally
{
// finally中的总是被调用
console.log('i am in finally');
} try
{
notExists();
}
catch (e)
{
// 判断错误的实例化类型
if (e instanceof EvalError)
console.log('this is a EvalError');
else if (e instanceof SyntaxError)
console.log('this is a SyntaxError');
else if (e instanceof ReferenceError)
console.log('this is a ReferenceError');
else
console.log('An unknown errorr');
}
// 对Error对象重写
function myError(msg)
{
this.name = "myError'sname";
this.message = msg || "myError'info";
}
// 通过Object.create()创建错误原型
myError.prototype = Object.create(Error.prototype);
myError.prototype.constructor = myError;
try
{
throw new myError();
}
catch (e)
{
console.log(e.name);
console.log(e.message);
}
自定义对象
- 通过var obj = {} 对象字面量法
- 通过var obj = new Object()创建
- 通过函数构造创建对象
p.s. 使用的时候通过new操作符得到对象
用构造器创建对象的时候可以接收参数
构造器函数的首字母最好大写,区别其他的一般函数
- function Person(){}
- var Persion = function(){}
- 构造器属性(constructor property)
- 当我们创建对象的时候,实际上同时也赋予了该对象一种特殊的属性,即构造器属性
- 这个构造器属性实际上是一个指向用于创建该对象的构造器函数的引用
- 通过instanceof操作符可以检测一个对象是否由某个指定的函数构造器创建
- 通过Object.create()创建对象
/***********************************
* 对象字面量
***********************************/
var oTest = {};
document.write(typeof oTest + "</br>");
var oTest2 = { x: 1, 'y': 2, "z": 3 };
document.write(oTest2.x + " " + oTest2.y + " " + oTest2.z + "</br>");
var oTest3 = {
username: 'rog91222',
passwd: '123123',
person: {
firstname: "hugh",
lastname: "dong"
},
age: 20
}
document.write(oTest3.username + " " + oTest3.person.firstname + " " + oTest3.age + "</br>");
/***********************************
* new Object()创建对象
***********************************/
var oTest4 = new Object();
/***********************************
* 通过构造器函数的形式创建对象
***********************************/
function funcTest(num1, num2) {
this.n1 = num1;
this.n2 = num2;
}
var oTest5 = new funcTest(1, 2);
document.write(oTest5.n1 + " " + oTest5.n2 + "</br>");
// 通过instanceof检测是否由函数构造器构造的
document.write(oTest5 instanceof funcTest);
document.write("<br>")
/***********************************
* 通过Object.create()创建对象
***********************************/
var oTest6 = Object.create({ x: 1 });
// 不继承任何方法
var oTest7 = Object.create(null);
// 创建一个普通的空对象
var oTest8 = Object.create(Object.prototype);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
对象特性
- 原型(prototype)
- 通过对象字面量的形式创建,则使用object.prototype作为它们的原型。
- 通过new和构造函数创建,则使用构造函数的prototype作为它们的原型。
- 如果通过Object.create()创建,使用第一个参数(或null)作为它们的原型
var obj = Object.create({ x: 1 });
- 类(class)
- 扩展标记(extensible flag)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
对象的结构
- 声明对象obj,对象有2个属性 x=1,y=2,每个属性都有对应的属性特性,对象也有3个对象特性
- 对象的原型链:
如图所示,当在对象中找不到属性z时,会向方法的原型查找,继续向对象的原型查找,直到顶层null位置。
每个对象都和另外一个对象关联,就构成了一个原型链,每一个对象都从原型继承属性。
<<test.js>>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
检测对象上是否有某个属性
- in(包括原型上的)
- hasOwnProperty(仅检测对象自己有的属性)
function foo() {}
foo.prototype.z = 5;
var obj1 = new foo();
obj1.x = 1;
obj1.y = 2;
console.log('x' in obj1);
console.log('y' in obj1);
console.log('toString' in obj1);
console.log('nonono' in obj1);
console.log(obj1.hasOwnProperty('x'));
console.log(obj1.hasOwnProperty('z'));
————————————————————————————————————————————
属性
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
数据属性:每个属性有4个描述行为的特性:
- [writable]:是否能修改属性的值
- [enumerable]:是否通过for in 循环返回属性(是否可以被枚举)
- [configurable]:是否能通过delete删除,能否修改属性的特性,能否修改访问器属性
- [value]:包含这个属性的数据值,读取属性值的时候从这个位置读取。默认值为undefined
存取器属性
- get:获取属性的值
- set:设置属性的值
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性操作
p.s. 正常属性名可以放在""''或不放引号内,但如果包含特殊字符、保留字、数字开头,必须放在引号之间
- 访问属性
- 添加属性
- 修改属性
- 删除属性
- 遍历属性
var person =
{
fName : 'hugh',
lName : 'dong',
age : 20
};
// 通过.或[]来实现查询属性
console.log(person.fName);
console.log(person['lName']);
console.log(person["age"]);
// 如果属性不确定,需要使用[]来读取属性,此处key不能加引号
var key = 'fName';
console.log(person[key]);
// 在对象内部通过this获取属性
function PersonInfo(fName, lName, age)
{
this.firstName = fName;
this.lastName = lName;
this.year = age;
}
var person1 = new PersonInfo('wang', 'er', 30);
console.log(person1.firstName);
console.log(person1.lastName);
console.log(person1.year);
// 添加属性
var obj = {};
obj.userName = 'username';
obj.passwd = '123456';
obj['permissions'] = 'admin';
console.log(obj.userName);
console.log(obj.passwd);
console.log(obj.permissions);
// 修改属性
obj.passwd = '123.com';
console.log(obj.passwd);
// 删除属性,删除后再打印该属性为undefined
// p.s.delete只能删除自身的属性,不能删除集成的属性
// 要删除继承属性,只能从定义它的属性的原型对象上删除它,会影响到所以继承这个原型的对象
// delete只是断开属性和宿主对象的联系,而不会去操作属性的属性
delete obj.permissions;
console.log(obj.permissions);
// 遍历属性
// i存放的是属性名称,obj[i]存放的是属性值
for (var i in obj)
{
console.log(i + ":" + obj[i]);
}
// 对象中有方法
var obj1 =
{
user : '111',
pass : '222',
sayHi : function (x)
{
return this.user + x + 1;
}
}
console.log(obj1.sayHi(3));
JavaScript | 对象与属性的更多相关文章
- JavaScript 对象 - 与属性的相关知识
function inherit(p){ if(p == null) throw TypeError(); if(Object.create) return Object.create(p); var ...
- JavaScript对象之属性标签
本文介绍一下js对象的属性标签(configurable.writable.enumerable.value.get.set)的使用. 上图的要点为: 1.Object.getOwnPropertyD ...
- 了解JavaScript 对象的属性操作
提起操作, 很多人都会想到我们学习过程中最经常做的操作, 就是对数据库进行增, 删, 改, 查, 既然提到这个, 那么对于对象的属性操作也不例外, 基本上可以说也是这几个操作. JS中对象的属性标签 ...
- javascript对象的属性,方法,prototype作用范围分析.
用了javascript这么久由于没有系统学习过基础,总是拿来主义. 所以对一些基础知识还是搞不清楚很混乱. 今天自己做个小例子,希望彻底能搞清楚. 注释中对象只例子的对象本身,原型只原型继承对象的新 ...
- javascript对象constructor属性
概述 返回一个指向创建了该对象原型的函数引用.需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串.对于原始值(如1,true 或 "test"),该属性为只读. ...
- JavaScript对象遍历属性和值
原文链接:http://caibaojian.com/javascript-object-3.html 加入你输出来一个对象,但是苦于不知道里面有哪些属性和值,这个时候,你可以通过下面的代码来遍历这个 ...
- JavaScript对象之属性操作
在js对象中,我们可以对对象属性进行操作. 上图的要点为:for-in会把原型链上的可枚举属性也列出来. 上图的要点为:可以使用逻辑运算符&&进行层层查找对象是否为undefined, ...
- 删除要被替换的元素的所有事件处理 程序和 JavaScript 对象属性
使用本节介绍的方法替换子节点可能会导致浏览器的内存占用问题,尤其是在 IE 中,问题更加明显.在删除带有事件处理程序或引用了其他 JavaScript 对象子树时,就有可能导致内存占用问题.假设 某个 ...
- JavaScript对象属性
JavaScript对象的属性有两类:数据属性和访问器属性 数据属性 数据属性有四个特性,分别为: [[value]]属性的值 [[writeable]]属性是否可以修改 [[enumerable]] ...
随机推荐
- 实例教程:1小时学会Python(转)
1 序言 面向读者 本文适合有经验的程序员尽快进入Python2.x世界.特别地,如果你掌握Java和Javascript,不用1小时你就可以用Python快速流畅地写有用的Python程序. Pyt ...
- 27、Django实战第27天:全局搜索功能开发
当我们选择其中一个类别(公开课,课程讲师,授课老师),输入搜索内容,点击搜索后会跳转到相应的列表页中进行展示 我们输入的内容作为参数keyword传入后台 搜索"公开课" 当课程中 ...
- Eclipse Build all and build project not working - jar missing
Eclipse Build all and build project not working - jar missing
- RPD Volume 172 Issue 1-3 December 2016 评论02
Introduction to the special issue of Radiation Protection Dosimetry This special issue is a collecti ...
- [BZOJ5461][LOJ#2537[PKUWC2018]Minimax(概率DP+线段树合并)
还是没有弄清楚线段树合并的时间复杂度是怎么保证的,就当是$O(m\log n)$吧. 这题有一个显然的DP,dp[i][j]表示节点i的值为j的概率,转移时维护前缀后缀和,将4项加起来就好了. 这个感 ...
- 【数形结合】Gym - 100923I - Por Costel and the Pairs
perechi3.in / perechi3.out We don't know how Por Costel the pig arrived at FMI's dance party. All we ...
- 【Heap-Dijkstra】【分层图】bzoj2763 [JLOI2011]飞行路线
建立k+1张图, 在图与图之间,若在原图中x到y有边,就建立从 第i层的x 到 i+1层的y 建边,权值为0.代表一次免费机会. 由于一旦到了第i+1层的图里,则无法回到之前的层,所以免费最多只有k次 ...
- 数据访问与sql语句的管理(一)
在开发过程中数据访问是必不可少的.每个框架都会有自己数据访问机制.大家在一般的情况下会为自己的框架配备2套数据访问机制,ORM和DataHelper.当然,根据项目的需要有时候也可能只一种. 其实这2 ...
- 【mybatis】mybatis 中select 查询 select * 查询出来的数据,字段值带不出来 数据不全
原来的代码如下: <select id="findByGoodsUid" resultType="com.pisen.cloud.luna.ms.goods.bas ...
- VisualSVN设置提交时必须输入log信息
在别人的基础上修改的: 自己在Windows上用VisualSVN搭了个服务器,默认提交代码是可以不填任何信息,这可不是我所期望的,于是找到了下面的解决方案: 在VisualSVN的管理控制台中可以设 ...