所以我们建议一般JavaScript代码放在Body最下面,且最好是通过外链式
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <!--CSS样式建议放在head,外部调用-->
- <link type="text/css" rel="stylesheet" href="xiaomi_box/box_css.css">
- </head>
- <body>
- <!--HTML页面内容 -->
- <!-- 建议放在body最下面,外部调用-->
- <script type="application/javascript" src="4-1.js"></script>
- </body>
- </html>
JavaScript数据类型分为两类:原始类型(primitive type)和对象类型(object type)
原始类型:
数字、字符串、布尔值、还有两个特殊的原始值(null[空值]和undefined[未定义])
对象类型:
1、普通对象(集合-可以理解为字典且无序)
对象是属性的集合每个属性都是由"名/值组成" 可以理解为Python中的字典擦~ 这个值可以是原始类型的数字、字符串也可以是对象
2、全局对象
有一个特殊的对象Global object
3、数组对象(有序的集合可以理解为列表)
数组(array),有序的集合可以理解为Python中的列表
4、函数对象
首先JavaScript里面没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承。
重要的事情说三遍:JavaScript中没有类和实例的概念他是一个纯面向对象的语言,你可以理解为它的对象是靠一个对象来创建的
网景公司在发明与设计JavaScript的目标,其中很重要的两点:
1. 简易版的Java;
2. 简易,简易还是简易。
Brendan Eich设计JavaScript的时候引入了Java一个非常重要的概念:一切皆对象。既然JavaScript里面有了对象,那么设不设计继承就是困扰Brendan Eich的一个问题,如果真是要设计一个简易的语言其实可以不要继承机制,继承属于专业的程序员,但是JavaScript里那么多的对象,如果没有一种机制,他们之间将如何联系了,这必然会对编写程序的可靠性带来很大的问题,但是引入了继承又会使用JavaScript变成了完整的面向对象的语言,从而提高了它的门槛,让很多初学者望而却步,折中之下,Brendan Eich还是选择设计继承,但绝不是标准的继承(说道这里我想起了同样使用EMCAScript标准设计的语言ActionScript,它里面就有很完整的继承,做起来很惬意,我常想这是不是JavaScript以后的趋势,说不定哪天JavaScript会变的搄更完美写了?)。折中是指Brendan Eich不打算引入类(class),这样JavaScript至少看起来不像面向对象的语言了,那么初学者就不会望而却步了(这是欺骗啊,进来后倒腾死你,这就是所谓的关门打狗了,而且现在不还是引入了class吗,但是这个class实际还是调用了原型链)。
Brendan Eich思考之后,决定借鉴C++和java的new命令,将new命令引入了JavaScript,在传统的面向对象的语言里,new 用来构造实例对象,new 会调用构造函数,但是传统面向对象的语言new 后面的是类,内部机制是调用构造函数(constructor),而Brendan Eich简化了这个操作,在JavaScript里面,new 后面直接是构造函数,如是我们可以这么写一个Person类:
- function Person(name) {
- this.name = name
- }
- let personOne = new Person("Brendan Eich");
- console.log(personOne.name)
这样就创建了一个新的实例了。但是new有缺陷。用构造函数生成实例对象是无法无法共享属性和方法,例如下面代码:
- function Person(name) {
- this.name = name;
- this.nation = 'USA';
- }
- let person1 = new Person("Brendan Eich");
- let preson2 = new Person("Shuai Ge");
- person1.nation = "China";
- console.log(person1.nation); // China
- console.log(preson2.nation); // USA
每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。和JavaScript工厂模式的缺点一样,过多重复的对象会使得浏览器速度缓慢,造成资源的极大的浪费。
考虑到这一点,Brendan Eich决定为构造函数设置一个prototype属性,这个属性都是指向一个prototype对象。下面一句话很重要:所有实例对象需要共享的属性和方法,都放在这个Prototype对象(原型对象)里面;那些不需要共享的属性和方法,就放在构造函数里面。
实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。如是我们可以改写下上面的程序:
- function Person(name) {
- this.name = name;
- }
- // 我们不需要指定prototype对象当我们创建对象的时候默认会生成
- Person.prototype = {nation: "USA"};
- let person1 = new Person("Brendan Eich");
- let person2 = new Person("Shuai Ge");
- console.log(person1.nation);
- console.log(person2.nation);
当我们这样写程序时候Person.prototype.nation = 'China'; 所有实例化的类的nation都会变成China。
由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样。prototype只是提供了实现JavaScript继承的一个很方便的途径和手段。
5、日期、正则、错误 三种有用的对象
从字面上就可以看出日期是就代表日期的对象,正则表达式对象,还有就是定义了错误的对象
总结一下就是:数字、字符串、布尔值、null、undefined、对象(集合-字典)、数组(列表)、函数、日期、正则、错误这些对象类型,记住一切皆对象
数字类型
1、JavaScript中的数字是不区分整数和浮点数的,它们默认都是采用浮点数展示
默认ES5是支持16进制的,但是不支持8进制,在ES6中明确了二进制采用[0b或0B],8机制采用[0o或0O]表示
2、数字的+、-、*、/、加减乘除
这些复杂的运算符都是通过Math对象属性定义的函数和常量实现的
3、二进制浮点数和四舍五入误差
首先要明确一点在计算机的世界里计算机只是别0,1,我们平时看到的任何 在计算机的理解力都是0,1,只是在我们看前做了一个转换,有了这个前提我们来看下
- console.log(0.1 + 0.2 )
- // 0.30000000000000004
what's FK ~ 什么鬼?JavaScript采用了IEEE-754表示法基本上现代编程语言都采用的是这个,你以为其他语言就会是对的吗?天真你试试~~
原因是:
- 那么0.1和0.2转换成二进制分别是,
- (0.1) => 0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 101
- (0.2) => 0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 01
- 然后对上面的两个二进制数字做加法,得到的结果是,
- 0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1101 01
- 再把这个二进制转换成十进制,就是我们前面的结果0.30000000000000004了
有写语言没有这个问题说明本质上对其做了封装~
ES6中也没有对其进行封装只提供了一个误差值~~!
那我们应该如何解决这个问题呢?两种方法:
变大求值
我们把float值放大N倍后为正数在进行计算
- let a = 0.1;
- let b = 0.2;
- let ret = (a * 10 + b * 10) / 10;
- console.log(ret);
字符串求值
- let a = 0.1;
- let b = 0.2;
- let ret = (a + b).toFixed(1);
- let newRet = parseFloat(ret);
- console.log(newRet);
日期类型
JavaScript语言核心包括Date()构造函数,用来创建表示日期和时间对象。这些日期对想的方法为计算提供了简单的API
- let beforDate = new Date(2011, 0, 1); // 2011年1月1日
- let laterDate = new Date(2011, 0, 1, 17, 10, 30); //同一天,当地时间5:10:30pm
- let nowDate = new Date(); // 当前日期和时间
- let elapsed = nowDate - laterDate; //日期减法: 计算时间检核的毫秒数
- laterDate.getFullYear(); // ==> 2011 获取年份
- laterDate.getMonth(); // ==> 0 获取从0计数的月份
- laterDate.getDay(); // ==> 5 得到星期几,0代表星期日,5代表星期一
- laterDate.getHours(); // ==> 17:5pm 当地时间
- laterDate.getUTCHours(); // 使用UTC表示小时的时间,基于时区
来源: http://www.cnblogs.com/luotianshuai/p/7505300.html