js创建对象,用函数实现对象创建,并实现内函数共享
除了直接用{ ... }
创建一个对象外,JavaScript还可以用一种构造函数的方法来创建对象。它的用法是,先定义一个构造函数:
function Student(name) {this.name = name;this.hello = function () {alert('Hello, ' + this.name + '!');}
}
你会问,咦,这不是一个普通函数吗?
这确实是一个普通函数,但是在JavaScript中,可以用关键字new
来调用这个函数,并返回一个对象:
var xiaoming = new Student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // Hello, 小明!
用new Student()
创建的对象还从原型上获得了一个constructor
属性,它指向函数Student
本身:
xiaoming.constructor === Student.prototype.constructor; // true
Student.prototype.constructor === Student; // trueObject.getPrototypeOf(xiaoming) === Student.prototype; // truexiaoming instanceof Student; // true
看晕了吧?用一张图来表示这些乱七八糟的关系就是:
红色箭头是原型链。注意,Student.prototype
指向的对象就是xiaoming
、xiaohong
的原型对象,这个原型对象自己还有个属性constructor
,指向Student
函数本身。
另外,函数Student
恰好有个属性prototype
指向xiaoming
、xiaohong
的原型对象,但是xiaoming
、xiaohong
这些对象可没有prototype
这个属性,不过可以用__proto__
这个非标准用法来查看。
现在我们就认为xiaoming
、xiaohong
这些对象“继承”自Student
。
不过还有一个小问题,注意观察:
xiaoming.name; // '小明'
xiaohong.name; // '小红'
xiaoming.hello; // function: Student.hello()
xiaohong.hello; // function: Student.hello()
xiaoming.hello === xiaohong.hello; // false
xiaoming
和xiaohong
各自的name
不同,这是对的,否则我们无法区分谁是谁了。
xiaoming
和xiaohong
各自的hello
是一个函数,但它们是两个不同的函数,虽然函数名称和代码都是相同的!
如果我们通过new Student()
创建了很多对象,这些对象的hello
函数实际上只需要共享同一个函数就可以了,这样可以节省很多内存。
要让创建的对象共享一个hello
函数,根据对象的属性查找原则,我们只要把hello
函数移动到xiaoming
、xiaohong
这些对象共同的原型上就可以了,也就是Student.prototype
:
修改代码如下:
function Student(name) {this.name = name;
}Student.prototype.hello = function () {alert('Hello, ' + this.name + '!');
};
用new
创建基于原型的JavaScript的对象就是这么简单!
忘记写new怎么办
如果一个函数被定义为用于创建对象的构造函数,但是调用时忘记了写new
怎么办?
在strict模式下,this.name = name
将报错,因为this
绑定为undefined
,在非strict模式下,this.name = name
不报错,因为this
绑定为window
,于是无意间创建了全局变量name
,并且返回undefined
,这个结果更糟糕。
所以,调用构造函数千万不要忘记写new
。为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写,而普通函数首字母应当小写,这样,一些语法检查工具如jslint将可以帮你检测到漏写的new
。
最后,我们还可以编写一个createStudent()
函数,在内部封装所有的new
操作。一个常用的编程模式像这样:
function Student(props) {this.name = props.name || '匿名'; // 默认值为'匿名'this.grade = props.grade || 1; // 默认值为1
}Student.prototype.hello = function () {alert('Hello, ' + this.name + '!');
};function createStudent(props) {return new Student(props || {})
}
这个createStudent()
函数有几个巨大的优点:一是不需要new
来调用,二是参数非常灵活,可以不传,也可以这么传:
var xiaoming = createStudent({name: '小明'
});xiaoming.grade; // 1
如果创建的对象有很多属性,我们只需要传递需要的某些属性,剩下的属性可以用默认值。由于参数是一个Object,我们无需记忆参数的顺序。如果恰好从JSON
拿到了一个对象,就可以直接创建出xiaoming
。
实例:
<script>
function Student(props) {
this.name = props.name || '匿名'; // 默认值为'匿名'
this.grade = props.grade || 1; // 默认值为1
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
};
function createStudent(props) {
return new Student(props || {})
}
alert(JSON.stringify(createStudent({"name":"小明"})));
</script>
</body>
</html>
实例2:
function Cat(name) {
this.name=name;
}
Cat.prototype.say=function(){
alert('Hello, '+this.name.toString()+'!');
return 'Hello, '+this.name.toString()+'!'
};
// 测试: var kitty = new Cat('Kitty'); var doraemon = new Cat('哆啦A梦'); if (kitty && kitty.name === 'Kitty' && kitty.say && typeof kitty.say === 'function' && kitty.say() === 'Hello, Kitty!' && kitty.say === doraemon.say) {console.log('测试通过!'); } else {console.log('测试失败!'); }
js创建对象,用函数实现对象创建,并实现内函数共享相关推荐
- JS中的函数,Array对象,for-in语句,with语句,自定义对象,Prototype
一)函数 A)JS中的函数的定义格式: function add(a,b) { var sum = a+b; document.write("两个数的和是:" + sum); // ...
- 声明对象 创建对象_流利的对象创建
声明对象 创建对象 关于此主题的文章很多(绝大多数),但我只是想贡献我的两分钱,并写一篇简短的文章,介绍如何使用Java中的Fluent Object Creation模式或对象构建器实例化Value ...
- js 事件回调函数的对象属性说明:clientX、screenX、offsetX、pageX
clientX 鼠标相对于浏览器左上角x轴的坐标: 不随滚动条滚动而改变: clientY 鼠标相对于浏览器左上角y轴的坐标: 不随滚动条滚动而改变: pageX 鼠标相对于浏览器左上角x轴的坐标: ...
- JS函数和对象(一)
在本文章中,将对JS中的函数和对象进行一些讲解,不对之处还请之处 一.JS中的函数 1.1无参函数 其形式如下代码所示 function box(){alert("我是一个函数,只有被调用才 ...
- JS自执行函数(立即调用)
先说分组操作符 先了解一下分组操作符 分组操作符其实就是() ,在js中有两种用法,一个是求值,一个是调用函数 将函数放在圆括号中,会返回函数本身.如果圆括号紧跟在函数的后面,就表示调用函数. ()中 ...
- 第163天:js面向对象-对象创建方式总结
面向对象-对象创建方式总结 1. 创建对象的方式,json方式 推荐使用的场合: 作为函数的参数,临时只用一次的场景.比如设置函数原型对象. 1 var obj = {}; 2 //对象有自己的 属性 ...
- js 对象创建及其继承的方法
重新看红皮书,觉得很多知识多看几遍确实是能看的更明白些.今天重温了一下对象创建和继承,就稍微记下来,巩固一下. js是面向对象的编程语言,ECMA-262吧对象定义为:"无序属性的集合,其属 ...
- 什么是创建对象java_什么是对象,以及对象的创建和方法
js中的对象分为两种,一种是面向对象另一种是遍历对象. 面向对象在js里有两bai个层次的含义,第一种是会使用面向对象函数:第二种是构造面向对象函数. js也是面向对象中的一种写法,不过相对于java ...
- Python OOP:面向对象基础,定义类,创建对象/实例,self,创建多个对象,添加对象属性,访问对象属性,__init__方法,带参数的__init__,__str__方法,__del__方法
一.理解面向对象 面向对象是⼀种抽象化的编程思想,很多编程语⾔中都有的⼀种思想. ⾯向对象就是将编程当成是⼀个事物,对外界来说,事物是直接使用的,不用去管他内部的情况.⽽编程就是设置事物能够做什么事. ...
- JS基础:变量、函数、对象、数组、循环、选择(判断)
JS基础:变量.函数.对象.数组.循环.选择(判断) js的三个组成部分 ECMAScript - ES - 语法规范 DOM - 文档对象模型 - API BOM - 浏览器对象模型 - API j ...
最新文章
- 单例Singleton
- 04-numpy-笔记-transpose
- Qt图形界面编程入门(6)
- Android之使用ThumbnailUtils类来获取视频第一帧缩略图
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第八部---怪物出场
- 流文件 服务器无响应,文件服务器配置程序未响应
- 解决Maven项目pom文件中出现的错误:Missing artifact oracle:ojdbc7:jar:12.1.0.2.0:compile
- java开发做项目的思路
- 涉密专用计算机平台,涉密计算机及移动存储介质保密管理系统(三合一)
- 点击查看详情显示更多布局
- 硬件特征码已达到最大上限_获取硬件特征码(硬盘,网卡,CPU)
- Spring文件上传接口学习(MultipartFile,MultiparHttpservletRequest,MultipartResolver)
- 华为路由器显示网络未连接到服务器,如何解决华为路由器Q1连接没有网络的问题?...
- 背包问题之0-1背包算法详解
- 过于自信,面试普通Java岗被面试官吊打了。。。
- 多媒体元素 video audio 兼容性 controls muted loop
- dtree做权限控制
- 苹果退款_苹果充值退款什么意思
- uniapp连接低功耗打印机实例,
- 关于端口号Port与TCP/UDP协议