JavaScript 对象操作、继承与模块化实现

1. Object 对象相关方法

Object.getPrototypeOf():返回参数对象的原型,是获取原型对象的标准方法。

var F = function () {};

var f = new F();

Object.getPrototypeOf(f) === F.prototype; // true

Object.setPrototypeOf():为参数对象设置原型,返回该参数对象。可用于模拟new命令。

var a = {};

var b = {x: 1};

Object.setPrototypeOf(a, b);

Object.getPrototypeOf(a) === b; // true

Object.create():以指定对象为原型,返回一个新的实例对象。还可接受第二个参数,用于添加实例自身的属性。

var A = { print: function () { console.log('hello'); } };

var B = Object.create(A);

B.print(); // hello

Object.prototype.isPrototypeOf():判断该对象是否为参数对象的原型,只要实例对象处在参数对象的原型链上,就返回true。

var o1 = {};

var o2 = Object.create(o1);

var o3 = Object.create(o2);

o2.isPrototypeOf(o3); // true

Object.prototype.proto:返回对象的原型,该属性可读写,但不建议使用,推荐用Object.getPrototypeOf()和Object.setPrototypeOf()。

var obj = {};

var p = {};

obj.proto = p;

Object.getPrototypeOf(obj) === p; // true

Object.getOwnPropertyNames():返回一个数组,成员是参数对象本身的所有属性的键名,不包含继承的属性键名。

Object.getOwnPropertyNames(Date);

Object.prototype.hasOwnProperty():判断某个属性定义在对象自身,还是定义在原型链上。

Date.hasOwnProperty('length'); // true

in运算符:返回一个布尔值,表示一个对象是否具有某个属性,不区分该属性是对象自身的还是继承的。

'length' in Date; // true

for...in循环:用于遍历对象的所有可遍历属性(包括自身和继承的)。

var o1 = { p1: 123 };

var o2 = Object.create(o1, { p2: { value: "abc", enumerable: true } });

for (p in o2) { console.info(p); }

2. 对象的继承

原型对象概述

构造函数的缺点:同一个构造函数的多个实例之间,无法共享属性,造成系统资源浪费。

function Cat(name, color) {

this.name = name;

this.color = color;

this.miaomiao = function () { console.log('喵喵'); };

}

var cat1 = new Cat('大毛', '白色');

var cat2 = new Cat('二毛', '黑色');

cat1.meow === cat2.meow; // false

prototype属性的作用:原型对象的所有属性和方法,都能被实例对象共享。

function Animal(name) { this.name = name; }

Animal.prototype.color = 'white';

var cat1 = new Animal('大毛');

var cat2 = new Animal('二毛');

cat1.color; // 'white'

原型链:所有对象都有自己的原型对象,形成一个 "原型链",最终都可以上溯到Object.prototype,其原型是null。

Object.getPrototypeOf(Object.prototype); // null

constructor属性:prototype对象的constructor属性默认指向prototype对象所在的构造函数,可用于得知实例对象的构造函数。修改原型对象时,一般要同时修改constructor属性。

function P() {}

P.prototype.constructor === P; // true

instanceof运算符

返回一个布尔值,表示对象是否为某个构造函数的实例,其实质是检查右边构造函数的原型对象是否在左边对象的原型链上。

var v = new Vehicle();

v instanceof Vehicle; // true

构造函数的继承

分两步实现:

在子类的构造函数中,调用父类的构造函数。

function Sub(value) {

Super.call(this);

this.prop = value;

}

让子类的原型指向父类的原型。

Sub.prototype = Object.create(Super.prototype);

Sub.prototype.constructor = Sub;

多重继承

JavaScript 不提供多重继承功能,但可通过变通方法实现,如 Mixin 模式。

function M1() { this.hello = 'hello'; }

function M2() { this.world = 'world'; }

function S() {

M1.call(this);

M2.call(this);

}

S.prototype = Object.create(M1.prototype);

Object.assign(S.prototype, M2.prototype);

S.prototype.constructor = S;

3. 模块化编程

基本的实现方法
把模块写成一个对象,所有的模块成员都放到这个对象里面,但会暴露所有模块成员。

var module1 = new Object({

_count : 0,

m1 : function (){ /*...*/ },

m2 : function (){ /*...*/ }

});

封装私有变量

构造函数的写法:将私有变量封装在构造函数中,但会导致构造函数与实例对象一体,耗费内存。

function StringBuilder() {

var buffer = [];

this.add = function (str) { buffer.push(str); };

this.toString = function () { return buffer.join(''); };

}

立即执行函数的写法:将相关的属性和方法封装在一个函数作用域里面,可达到不暴露私有成员的目的。

var module1 = (function () {

var _count = 0;

var m1 = function () { /*...*/ };

var m2 = function () { /*...*/ };

return { m1 : m1, m2 : m2 };

})();

模块的放大模式和宽放大模式

放大模式:为模块添加新方法。

var module1 = (function (mod){

mod.m3 = function () { /*...*/ };

return mod;

})(module1);

宽放大模式:适用于无法确定模块加载顺序的情况。

var module1 = (function (mod) { /*...*/ })(window.module1 || {});

输入全局变量

为保证模块的独立性,显式地将其他变量输入模块。

javascript

var module1 = (function ($, YAHOO) { /*...*/ })(jQuery, YAHOO);

相关推荐
讨厌吃蛋黄酥16 分钟前
🌟 React Router Dom 终极指南:二级路由与 Outlet 的魔法之旅
前端·javascript
轻语呢喃1 小时前
useMemo & useCallback :React 函数组件中的性能优化利器
前端·javascript·react.js
_未完待续2 小时前
Web 基础知识:CSS - 基础知识
前端·javascript·css
掘金012 小时前
初学者 WebRTC 视频连接教程:脚本逻辑深度解析
javascript·面试
GISer_Jing2 小时前
Node.js的Transform 流
前端·javascript·node.js
在钱塘江2 小时前
《你不知道的JavaScript-中卷》第一部分-类型和语法-笔记-4-强制类型转换
前端·javascript
皮皮虾仁2 小时前
让 VitePress 文档”图文并茂“的魔法插件:vitepress-plugin-legend
前端·javascript·vitepress
小飞机噗噗噗2 小时前
使用 react + webSocket 封装属于自己的hooks组件
前端·javascript·websocket
Seeker3 小时前
无人机纯前端飞控实践:基于MQTT的Web端控制方案
javascript·无人机
1024小神3 小时前
cocos控制玩家飞机发射子弹的小逻辑,以及开发思维
前端·javascript