老网站改版,竞价推广直通车,简单网站建设教学视频,静态网页制作总结虽然使用Object构造函数或对象字面量可以方便地创建对象#xff0c;但这些方式有明显不足#xff1a;创建具有同样接口的多个对象需要重复编写很多代码
工厂模式可以用不同的参数多次调用函数#xff0c;每次都会返回一个新对象#xff0c;这种模式虽然可以解决创建多个类…虽然使用Object构造函数或对象字面量可以方便地创建对象但这些方式有明显不足创建具有同样接口的多个对象需要重复编写很多代码
工厂模式可以用不同的参数多次调用函数每次都会返回一个新对象这种模式虽然可以解决创建多个类似对象的问题但没有解决对象表示问题即新创建的对象是什么类型
构造函数和工厂函数的区别
没有显式的创建对象属性和方法字节赋值给了this没有return
使用new操作符调用构造函数会执行如下操作
在内存中创建一个新对象这个新对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性构造函数内部的this被赋值为这个新对象即this指向新对象执行构造函数内部的代码给新对象添加属性如果构造函数返回非空对象则返回该对象否则返回刚创建的新对象
constructor本来是用于标识对象类型的不过一般认为instanceof操作符是确定对象类型更可靠的方式
相比于工厂模式定义自定义构造函数可以确保实例被标识为特定类型。
构造函数不一定要写成函数声明的形式赋值给变量的函数表达式也可以表示构造函数在实例化时如果不想传参数那么构造函数后面的括号可加可不加。只要有new操作符就可以调用相应的构造函数
构造函数与普通函数唯一的区别就是调用方式不同除此之外构造函数也是函数并没有把某个函数定义为构造函数的特殊语法。任何函数只要使用new操作符调用就是构造函数而不是用new操作符调用的函数就是普通函数。
构造函数的主要问题在于其定义的方法会在每个实例上都创建一遍因为都是做一样的事所以没必要定义两个不同的Function实例况且this对象可以把函数与对象的绑定推迟到运行时 每个函数都会创建一个prototype属性这个属性是一个对象包含应该由特定引用类型的实例共享的属性和方法。实例上这个对象就是通过调用构造函数创建的对象的原型使用原型对象的好处是在它上面定义的属性和方法可以被对象实例共享。原来在构造函数中直接赋给对象实例的值可以直接赋值给它们的原型
无论何时只要创建一个函数就会按照特定的规则为这个函数创建一个prototype属性指向原型对象默认情况下所有原型对象自动获得一个名为constructor的属性指回与之关联的构造函数。
在自定义构造函数时原型对象默认只会获得constructor属性其他的所有方法都继承自Object每次调用构造函数创建一个新实例这个实例的内部[[Prototype]]指针就会被赋值为构造函数的原型对象。脚本中没有访问这个[[Prototype]]的标准方式一些浏览器会在每个对象上暴露__proto__属性通过这个属性可以访问对象的原型。
实例与构造函数原型之间有直接的联系但实例与构造函数之间没有
虽然不是所有实现都对外暴露了[[Prototype]]但可以使用isPrototypeOf()方法确定两个对象之间的关系isPrototypeOf()会在传入参数的[[Prototype]]指向调用它的对象时返回true
Object有一个方法叫Object.getPrototype()返回参数的内部特性[[Prototype]]的值
Object.setPrototypeOf()可以向实例的私有特性[[Prototype]]写入一个新值这样就可以重写一个对象的原型继承关系但是会影响代码性能
Object.create()可以创建一个新对象同时为其指定原型
原型层级
在通过对象访问属性时会按照这个属性的名称开始搜索搜索开始于对象实例本身如果在这个实例上发现了给定的名称则返回该名称对应的值如果没有找到这个属性则搜索会沿着指针进入原型对象然后在原型对象上找到属性后再返回对应的值这就是原型用于在多个对象实例间共享属性和方法的原理
虽然可以通过实例读取原型对象上的值但不能通过实例重写这些值如果在实例上添加了一个原型对象中同名的属性那就会在实例上创建这个属性这个属性会遮住原型对象上的属性。
使用delete操作符可以删除实例上的属性
hasOwnProperty()方法用于确定某个属性是在实例上还是在原型对象上这个方法是继承自Object的会在属性存在于调用它的对象实例上时返回true
原型和in操作符
有两种方式使用in操作符单独使用和在for-in循环中使用
在单独使用时in操作符会在可以通过对象访问指定属性时返回true无论该属性在实例上还是原型上。
如果要确定某个属性是否在原型上可以同时使用hasOwnProperty()和in操作符
在for-in循环中使用in操作符时可以通过对象访问且可以被枚举的属性都会返回包括实例和原型属性
要获得对象上所有可枚举的实例属性可以使用Object.keys()方法这个方法接收一个对象作为参数返回包含该对象所有可枚举属性名称的字符串数组
如果想列出所有实例属性无论是否可以枚举都可以使用Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()方法针对符号
属性枚举顺序
for-in循环和Object.keys()的枚举顺序是不确定的
Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和Object.assign()的枚举顺序是确定的先以升序枚举数值键然后以插入顺序枚举字符串和符号键在对象字面量中定义的键以它们逗号分隔的顺序插入 Object.values()和Object.entries()将对象内容转换为序列化的可迭代的格式它们接收一个对象返回它们内容的数组。Object.values()返回对象值的数组Object.entries()返回键值对的数组非字符串属性会被转换为字符串输出这两个方法执行对象的浅复制符号属性会被忽略
原型上搜索值是动态的所以即使实例在修改原型之前已经存在任何时候对原型对象的修改也会在实例上反映出来
实例的[[Prototype]]指针是在调用构造函数时自动赋值的这个指针即使把原型修改为不同的对象也不会变重写整个原型会切断最初原型与构造函数的联系但实例引用的仍然是最初的原型
重写构造函数上的原型之后再创建的实例才会引用新的原型
通过原生对象的原型可以取得所有默认方法的引用也可以给原生类型的实例定义新的方法。可以像修改自定义对象原型一样修改原生对象原型因此随时可以添加方法
原型模式弱化了向构造函数传递初始化参数的能力会导致所有实例默认都取得相同的属性值原型的最主要问题是它的共享特性