————————————————————————————————————————————

对象: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 | 对象与属性的更多相关文章

  1. JavaScript 对象 - 与属性的相关知识

    function inherit(p){ if(p == null) throw TypeError(); if(Object.create) return Object.create(p); var ...

  2. JavaScript对象之属性标签

    本文介绍一下js对象的属性标签(configurable.writable.enumerable.value.get.set)的使用. 上图的要点为: 1.Object.getOwnPropertyD ...

  3. 了解JavaScript 对象的属性操作

    提起操作, 很多人都会想到我们学习过程中最经常做的操作, 就是对数据库进行增, 删, 改, 查, 既然提到这个, 那么对于对象的属性操作也不例外, 基本上可以说也是这几个操作. JS中对象的属性标签 ...

  4. javascript对象的属性,方法,prototype作用范围分析.

    用了javascript这么久由于没有系统学习过基础,总是拿来主义. 所以对一些基础知识还是搞不清楚很混乱. 今天自己做个小例子,希望彻底能搞清楚. 注释中对象只例子的对象本身,原型只原型继承对象的新 ...

  5. javascript对象constructor属性

    概述 返回一个指向创建了该对象原型的函数引用.需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串.对于原始值(如1,true 或 "test"),该属性为只读. ...

  6. JavaScript对象遍历属性和值

    原文链接:http://caibaojian.com/javascript-object-3.html 加入你输出来一个对象,但是苦于不知道里面有哪些属性和值,这个时候,你可以通过下面的代码来遍历这个 ...

  7. JavaScript对象之属性操作

    在js对象中,我们可以对对象属性进行操作. 上图的要点为:for-in会把原型链上的可枚举属性也列出来. 上图的要点为:可以使用逻辑运算符&&进行层层查找对象是否为undefined, ...

  8. 删除要被替换的元素的所有事件处理 程序和 JavaScript 对象属性

    使用本节介绍的方法替换子节点可能会导致浏览器的内存占用问题,尤其是在 IE 中,问题更加明显.在删除带有事件处理程序或引用了其他 JavaScript 对象子树时,就有可能导致内存占用问题.假设 某个 ...

  9. JavaScript对象属性

    JavaScript对象的属性有两类:数据属性和访问器属性 数据属性 数据属性有四个特性,分别为: [[value]]属性的值 [[writeable]]属性是否可以修改 [[enumerable]] ...

随机推荐

  1. ros pcl sensor::pointcloud2 转换成pcl::pointcloud

    #include <pcl_conversions/pcl_conversions.h> #include <pcl/point_types.h> #include <p ...

  2. ros中删除某个包之后用apt安装的包找不到

    原因是工作空间devel里还存有原来的二进制可执行文件,将build和devel内容全删除后再catkin_make就好了

  3. hdu5794

    从(u,v)到(n,m)相当于走x步1*2和y步2*1满足 x+2y=n-u,2x+y=m-v 解方程然后组合计数即可. 以前没写过lucas定理,写一下…… 其实就是C(n,m)%p=C(n/p,m ...

  4. [scrapy] PIL老是出错,换成pillow解决问题

    使用scrapy下载图片的时候,用PIL老是下载不成功 出现如下错误: IOError: encoder jpeg not available 据说是安装PIL之前缺少一些相关的包 freetype ...

  5. PHP abstract与interface之间的区别

    1.php 接口类:interface 其实他们的作用很简单,当有很多人一起开发一个项目时,可能都会去调用别人写的一些类,那你就会问,我怎么知道他的某个功能的实现方法是怎么命名的呢,这个时候php接口 ...

  6. pyinstaller对多进程程序的打包

    在使用python的第三方库pyinstaller对多进程程序进行打包时,程序不能正常的运行,但是后台却有多个进程一直在使用资源. 解决方法很简单,在if __name__ == '__main__' ...

  7. 一个Sqrt函数引发的血案

    源码下载地址:http://diducoder.com/sotry-about-sqrt.html 好吧,我承认我标题党了,不过既然你来了,就认真看下去吧,保证你有收获. 我们平时经常会有一些数据运算 ...

  8. 概述struts,以及struts如何实现MVC架构的

    概述MVC体系结构? 答:MVC包括三类对象,model是应用对象,view是视图,controller是控制器,它定义用户界面对用户输入的响应方式. 在MVC体系中,模型通常被称为”业务逻辑”,是真 ...

  9. [BZOJ 3233] 找硬币

    Link: BZOJ 3233 传送门 Solution: 在本蒟蒻看来算是一道比较神的$dp$了 一开始转移方程都没看出来…… 首先,如果确定了最大面值,是能推出其他面值的所有可能值的 从而发现最大 ...

  10. 【三维偏序】【分块】bzoj3262 陌上花开

    裸的三维偏序. 对x坐标排序,y.z坐标分块.复杂度O(n*sqrt(n*log(n))).代码很短. #include<cstdio> #include<cmath> #in ...