博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript读书笔记(对象的总结)
阅读量:7103 次
发布时间:2019-06-28

本文共 9020 字,大约阅读时间需要 30 分钟。

JavaScript读书笔记(对象的总结)

一、创建对象的方式

  • 1、直接创建(常用)

    let obj = {  name: '哈哈',  gender: '男'}复制代码
  • 2、使用实例化对象的方式创建(比较少用)

    function Foo() {  //}let foo = new Foo()复制代码
  • 3、内置对象的实例

    let x1 = new Object();    // A new Object objectlet x2 = new String();    // A new String objectlet x3 = new Number();    // A new Number objectlet x4 = new Boolean();   // A new Boolean objectlet x5 = new Array();     // A new Array objectlet x6 = new RegExp();    // A new RegExp objectlet x7 = new Function();  // A new Function objectlet x8 = new Date();      // A new Date object复制代码
  • 4、使用工厂方式创建(很少用)

    function CreatePerson(name, age, sex) {  var obj = new Object();  obj.name = name;  obj.age = age;  obj.sex = sex;  obj.sayName = function () {    return this.name;  }  return obj;}let p1 = new CreatePerson('哈哈', 20, '男');复制代码

二、一些基本的属性或者方法

  • 1、每一个对象都有链接着原型对象的隐藏属性__proto__

    var obj = {};obj.__proto__ === Object.prototype; //true复制代码
  • 2、判断一个对象是否包含一个属性

    const obj2 = {
    gender: '男'};console.log('gender' in obj2);console.log('name' in obj2);// 也可以使用hasOwnPropertyconsole.log(obj2.hasOwnProperty('gender'));复制代码
  • 3、判断一个对象是否为空

    const obj2 = {
    gender: '男'};console.log(Object.keys(obj2));console.log(Object.values(obj2));复制代码
  • 4、删除一个属性

    const obj2 = {
    gender: '男', age: 20, name: '张三'};delete obj2.gender;console.log(obj2);// 也可以使用解析赋值的方式const {name, ...obj1} = obj2;console.log(obj1);复制代码
  • 4、Object.assign()的使用

    • 1.对象的合并
    • 2.对象的浅拷贝
    • 3.给对象新增属性/方法
    • 4.克隆对象(非深拷贝)
  • 5、判断是否为对象

    Object.prototype.toString.call(data).slice(8, -1)复制代码

三、关于对象中几个重要词的理解

  • 1、constructor查找该对象是由什么创建出来的

    let obj = {};let reg = new RegExp();let arry = new Array();let str = new String();let date = new Date();console.log(obj.constructor);console.log(reg.constructor);console.log(arry.constructor);console.log(str.constructor);console.log(date.constructor);// 继续往上面找console.log(Date.constructor);console.log(Function.constructor);复制代码
  • 2、instanceof判断构造函数是否在对象实例的原型链上

    Person.prototype.dance = function () {  return 'dance function';}// 定义一个子类function Foo() {}Foo.prototype = new Person();let foo = new Foo();/** * 修改Foo原型的constructor * 关于defineProperty几个参数的介绍 * 第一个参数:属性所在的对象,第二个参数:属性的名字,一个描素符对象  */Object.defineProperty(Foo.prototype, 'constructor', {  writable: false,  enumerable: false,  value: Foo,});let foo1 = new Foo();console.log(foo1 instanceof Foo);console.log(foo1 instanceof Person);console.log(foo1 instanceof Object);复制代码
  • 3、hasOwnProperty()判断一个对象是否拥有该属性

    var obj = {
    name: '哈哈', gender: '男'};obj.hasOwnProperty('name');复制代码
  • 4、setPrototypeOf()修改对象的原型

    function Foo() {};const foo = new Foo();// 每一个对象都有constructorlet bar = {};console.log(bar.constructor);// 修改bar的原型Object.setPrototypeOf(bar, foo);console.log(bar.constructor); // [Function: Foo]复制代码

四、配置对象的属性

  • 1、configurable: 如果为true表示可以修改与删除属性,如果为false就不能修改与删除

  • 2、enumerable: 如果为true表示为可枚举的可以使用for..in

  • 3、value:指定属性的值

  • 4、writable:如果为true表示可以通过赋值语句修改对象属性

  • 5、get定义gettter函数

  • 6、set定义setter函数

  • 7、测试案例

    let obj1 = {};obj1.name = '哈哈';obj1.gender = '男';// 定义第三个属性Object.defineProperty(obj1, 'address', {  configurable: false,  enumerable: true,  value: '深圳',  writable: false,});console.log(JSON.stringify(obj1));for (let key in obj1) {  console.log(`${key}===${obj1[key]}`);}复制代码

五、对象的一些扩展

  • 1、对象的私有属性

    function Foo() {  let name;  // 定义一个set方法赋值  this.setName = (newVal) => name = newVal;  // 定义一个get方法取值  this.getName = () => name;}let foo = new Foo();foo.setName('哈哈');console.log(foo.getName());复制代码
  • 2、对象的setget方法

    // 在对象中get与set只是在属性前面加上了一个关键词,但是依然是属性的方式调用const obj1 = {  name: '哈哈',  get getName() {    console.log('get方法');    return this.name;  },  set setName(newVal) {    this.name = newVal;  }};console.log(obj1.getName);// obj1.setName = '张三';// console.log(obj1.getName);console.log(obj1.name);复制代码
  • 3、使用defineProperty定义私有属性

    function Foo() {  let _age = 0;  // 扩展一个属性  Object.defineProperty(this, 'age', {    get() {      return _age;    },    set(newVal) {      _age = newVal;    }  })}let foo = new Foo();console.log(foo.age);foo.age = 10;console.log(foo.age);复制代码
  • 4、使用setget进行数据的校验

    function Foo() {  let _age = 0;  Object.defineProperty(this, 'age', {    get() {      return _age;    },    set(newVal) {      if (/\d+/.test(newVal)) {        _age = newVal;      } else {        throw new TypeError('必须是数字');      }    }  })}try {  let foo = new Foo();  console.log(foo.age);  foo.age = 10;  console.log(foo.age);  foo.age = '哈哈';} catch (e) {  console.log(e);}复制代码

六、关于原型的理解

  • 1、关于使用new关键词创建对象所发生的事情

    • 创建一个新对象
    • 将构造函数的作用域赋值给新对象(this指向新对象)
    • 执行构造函数的代码
    • 返回新的对象
  • 2、为什么要使用构造函数的原型

    在使用构造函数创建对象的时候,每new一次就会创建一个对象,不同的实例的同名函数是不相等的,因此创建很多重复的代码(每次new一个构造函数,上面的构造函数就会执行一次,就会在内存中开辟一块空间,指向新的堆对象,这样内存消耗比较大),我们希望代码尽可能的复用,就需要原型

    // 普通的创建一个构造函数function Animal(name, age) {  this.name = name;  this.age = age;  this.print = function() {    console.log(`${
    this.name}====${
    this.age}`); }}// 使用原型function Animal(name, age) { this.name = name; this.age = age;}Animal.prototype.print = function() { console.log(`${
    this.name}====${
    this.age}`);}复制代码
  • 3、所有的对象都有一个constructor指向原型

  • 4、构造函数都有prototype指向原型

七、深入理解类的继承(ES6前的版本)

在面向对象开发中继承的概念是,新对象复用旧对象上的属性和方法(有点类似拷贝Object.assign),类似生活中子继承父的财产及工具的概念

  • 1、一个构造函数的原型指定另外一个构造函数

    function Person() {}// 定义原型Person.prototype.dance = function () {  return 'dance function';};// 定义一个子类function Foo() {}Foo.prototype = Person.prototype;// 总结:采用这种方式来创建类的继承,只是地址指向(一个修改了,另外一个也会随之修改)复制代码
  • 2、一个构造函数的原型指定另外一个函数的实例对象

    function Person() {}// 定义原型Person.prototype.dance = function () {  return 'dance function';};// 定义一个子类function Foo() {}// Foo构造函数的原型指向Person的实例对象Foo.prototype = new Person();let foo = new Foo();console.log(foo.dance());// 这样继承的方式会造成Foo的原型丢失,直接指定了Personconsole.log(foo.constructor);console.log(foo instanceof Foo);// 总结:采用这种方式实现继承:造成Foo的原型丢失,直接指定了Person复制代码
  • 3、修正方式二中constructor的指向

    function Person() {}Person.prototype.dance = function () {  return 'dance function';}// 定义一个子类function Foo() {}Foo.prototype = new Person();let foo = new Foo();console.log(foo.constructor);// 修改Foo原型的constructorObject.defineProperty(Foo.prototype, 'constructor', {  writable: false,  enumerable: false,  value: Foo,});let foo1 = new Foo();console.log(foo1.constructor);// 总结:修正`constructor`的指向复制代码

八、采用class的方式创建类

  • 1、创建一个类

    class Person {  constructor(name, age) {    this.name = name;    this.age = age;  }  // 普通方法  say() {    return 'say...';  }  // 静态方法  static talk() {    console.log(this);    return '我是静态方法';  }}let p = new Person('哈哈', 20);console.log(Person.talk());复制代码
  • 2、实现类的继承

    class Animal {  constructor(name) {    this.name = name;  }  call() {    return '在叫';  }}class Dog extends Animal {  constructor(name, age) {    super(name);    this.age = age;  }  // 重写父类的方法  call() {    return `${
    this.name}在叫`; }}let dog = new Dog('大黄狗', 3);console.log(dog.call());复制代码
  • 3、使用setget方法

    class Person {  constructor() {    this.name = '哈哈';  }  set setName(newVal) {    this.name = newVal;  }  get getName() {    return this.name;  }}let p = new Person();console.log(p.getName);p.setName = '张三';console.log(p.getName);复制代码

九、Proxy的使用


ProxyES6中新增的对象,使用方式Proxy(目标对象,代理的对象)

主要有如下属性

  • get(target, propKey, receiver):拦截对象属性的读取,比如√proxy.foo和proxy['foo']√。

  • set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = vproxy['foo'] = v,返回一个布尔值。

  • has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。

  • deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。

  • ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。

  • getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。

  • defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。

  • preventExtensions(target):拦截Object.preventExtensions(proxy)`,返回一个布尔值。

  • getPrototypeOf(target):拦截Object.getPrototypeOf(proxy)`,返回一个对象。

  • isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。

  • setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。

  • apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)

  • construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)

  • 1、使用案例

    let targetObj = {
    name: '哈哈'};const proxy = new Proxy(targetObj, { set(target, key, val) { console.log(target); console.log(key); console.log(val); target[key] = val; }, get(target, key) { console.log(target); console.log(key); return key in target ? target[key] : '不存在这个key'; }, // 使用in的时候调用 has(target, key) { console.log(target, key) if (target.hasOwnProperty(key)) { return true; } else { return false; } }, deleteProperty(target, key) { if (target.hasOwnProperty(key)) { return true; } else { return false; } }});复制代码
  • 2、代理方法

    let targetObj = function () {  return '目标函数';};let proxy = new Proxy(targetObj, {  apply(target, ctx, args) {    console.log(target());    console.log(ctx);    console.log(args);    return 'apply 函数';  }});proxy(12, 20);复制代码

转载地址:http://hgkhl.baihongyu.com/

你可能感兴趣的文章
搭建PHP环境后PHPINFO()中没有MYSQL的解决方法--笔记
查看>>
安装RPM包遇到:warning: : Header V3 DSA/SHA1 Signature, key ID e8562897: NOKEY
查看>>
简单的Python登陆认证小程序
查看>>
我的友情链接
查看>>
递归法列出目录中的所有文件
查看>>
H3C的命令
查看>>
LAMP平台搭建
查看>>
linux xrdp0.6 安装
查看>>
草根IT江湖路之二:改变,破釜沉舟的斗争
查看>>
-bash-3.2$的模式
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
mac下PYTHON安装
查看>>
解决TwitterSDK出现Failed to get request token错误提示
查看>>
shell脚本从入门到复杂 其五(基本运算符)
查看>>
centos7系统rpm方式安装docker
查看>>
Hibernate+jsp实现分页
查看>>
cocos2d-x 小记
查看>>
20130629一个认识自己的日子
查看>>
nfs的优化
查看>>