除了直接用{ ... }创建一个对象外,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指向的对象就是xiaomingxiaohong的原型对象,这个原型对象自己还有个属性constructor,指向Student函数本身。

另外,函数Student恰好有个属性prototype指向xiaomingxiaohong的原型对象,但是xiaomingxiaohong这些对象可没有prototype这个属性,不过可以用__proto__这个非标准用法来查看。

现在我们就认为xiaomingxiaohong这些对象“继承”自Student

不过还有一个小问题,注意观察:

xiaoming.name; // '小明'
xiaohong.name; // '小红'
xiaoming.hello; // function: Student.hello()
xiaohong.hello; // function: Student.hello()
xiaoming.hello === xiaohong.hello; // false

xiaomingxiaohong各自的name不同,这是对的,否则我们无法区分谁是谁了。

xiaomingxiaohong各自的hello是一个函数,但它们是两个不同的函数,虽然函数名称和代码都是相同的!

如果我们通过new Student()创建了很多对象,这些对象的hello函数实际上只需要共享同一个函数就可以了,这样可以节省很多内存。

要让创建的对象共享一个hello函数,根据对象的属性查找原则,我们只要把hello函数移动到xiaomingxiaohong这些对象共同的原型上就可以了,也就是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创建对象,用函数实现对象创建,并实现内函数共享相关推荐

  1. JS中的函数,Array对象,for-in语句,with语句,自定义对象,Prototype

    一)函数 A)JS中的函数的定义格式: function add(a,b) { var sum = a+b; document.write("两个数的和是:" + sum); // ...

  2. 声明对象 创建对象_流利的对象创建

    声明对象 创建对象 关于此主题的文章很多(绝大多数),但我只是想贡献我的两分钱,并写一篇简短的文章,介绍如何使用Java中的Fluent Object Creation模式或对象构建器实例化Value ...

  3. js 事件回调函数的对象属性说明:clientX、screenX、offsetX、pageX

    clientX 鼠标相对于浏览器左上角x轴的坐标: 不随滚动条滚动而改变: clientY 鼠标相对于浏览器左上角y轴的坐标: 不随滚动条滚动而改变: pageX 鼠标相对于浏览器左上角x轴的坐标: ...

  4. JS函数和对象(一)

    在本文章中,将对JS中的函数和对象进行一些讲解,不对之处还请之处 一.JS中的函数 1.1无参函数 其形式如下代码所示 function box(){alert("我是一个函数,只有被调用才 ...

  5. JS自执行函数(立即调用)

    先说分组操作符 先了解一下分组操作符 分组操作符其实就是() ,在js中有两种用法,一个是求值,一个是调用函数 将函数放在圆括号中,会返回函数本身.如果圆括号紧跟在函数的后面,就表示调用函数. ()中 ...

  6. 第163天:js面向对象-对象创建方式总结

    面向对象-对象创建方式总结 1. 创建对象的方式,json方式 推荐使用的场合: 作为函数的参数,临时只用一次的场景.比如设置函数原型对象. 1 var obj = {}; 2 //对象有自己的 属性 ...

  7. js 对象创建及其继承的方法

    重新看红皮书,觉得很多知识多看几遍确实是能看的更明白些.今天重温了一下对象创建和继承,就稍微记下来,巩固一下. js是面向对象的编程语言,ECMA-262吧对象定义为:"无序属性的集合,其属 ...

  8. 什么是创建对象java_什么是对象,以及对象的创建和方法

    js中的对象分为两种,一种是面向对象另一种是遍历对象. 面向对象在js里有两bai个层次的含义,第一种是会使用面向对象函数:第二种是构造面向对象函数. js也是面向对象中的一种写法,不过相对于java ...

  9. Python OOP:面向对象基础,定义类,创建对象/实例,self,创建多个对象,添加对象属性,访问对象属性,__init__方法,带参数的__init__,__str__方法,__del__方法

    一.理解面向对象 面向对象是⼀种抽象化的编程思想,很多编程语⾔中都有的⼀种思想. ⾯向对象就是将编程当成是⼀个事物,对外界来说,事物是直接使用的,不用去管他内部的情况.⽽编程就是设置事物能够做什么事. ...

  10. JS基础:变量、函数、对象、数组、循环、选择(判断)

    JS基础:变量.函数.对象.数组.循环.选择(判断) js的三个组成部分 ECMAScript - ES - 语法规范 DOM - 文档对象模型 - API BOM - 浏览器对象模型 - API j ...

最新文章

  1. 单例Singleton
  2. 04-numpy-笔记-transpose
  3. Qt图形界面编程入门(6)
  4. Android之使用ThumbnailUtils类来获取视频第一帧缩略图
  5. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第八部---怪物出场
  6. 流文件 服务器无响应,文件服务器配置程序未响应
  7. 解决Maven项目pom文件中出现的错误:Missing artifact oracle:ojdbc7:jar:12.1.0.2.0:compile
  8. java开发做项目的思路
  9. 涉密专用计算机平台,涉密计算机及移动存储介质保密管理系统(三合一)
  10. 点击查看详情显示更多布局
  11. 硬件特征码已达到最大上限_获取硬件特征码(硬盘,网卡,CPU)
  12. Spring文件上传接口学习(MultipartFile,MultiparHttpservletRequest,MultipartResolver)
  13. 华为路由器显示网络未连接到服务器,如何解决华为路由器Q1连接没有网络的问题?...
  14. 背包问题之0-1背包算法详解
  15. 过于自信,面试普通Java岗被面试官吊打了。。。
  16. 多媒体元素 video audio 兼容性 controls muted loop
  17. dtree做权限控制
  18. 苹果退款_苹果充值退款什么意思
  19. uniapp连接低功耗打印机实例,
  20. 关于端口号Port与TCP/UDP协议

热门文章

  1. Word 2016问题导致无法创建其他博客账号
  2. Docker基础-容器操作
  3. mac 上搭建SVN
  4. OFbiz--HelloWorld
  5. XAMPP mysql远程连接
  6. R语言基于S3的面向对象编程
  7. 创业宝典:未来企业家之路(第5版)
  8. tkinter中combobox下拉选择控件(九)
  9. 设计原则 里氏替换原则
  10. 6_Selenium Excel参数化