🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## **3.2.1 变量** ​ 变量本质是一个空盒子,里面记录了一个内存地址,使能找到内存中的对象,保存了指向具体的实在的东西的地址,变量存在栈中,对象存在堆中; ​ 变量的意义:方便我们去操作对象。变量的几种引用方式 - 指针(C语言中叫法) - 引用(Java) - 变量 > 例如: > var b = document.body 含义:把body这个对象在内存中的地址放到b变量里面,变量b(b是内存地址的别名)本身也存在内存中,以后的操作是针对body这个地址 ​ 变量命名规范 - 由字母(a-zA-Z)数字(0-9)下划线(_)以及美元符号($) - 不能由数字开头 - 命名尽量用英文并且具有一定的含义 - 如果有多个英文单词,后面单词的首字母大写 - 不能使用关键字 - 首字母不要大写,大写是有特殊含义的 <br/> ## **3.2.2 JS数据类型** **Javascript的数据类型有六种(ES6新增了第七种Symbol)** - 数值(number):整数和小数(比如1和3.14) - 字符串(string):字符组成的文本(比如”Hello World”) - 布尔值(boolean):true(真)和false(假)两个特定值 - undefined:表示 未定义 或不存在,即此处目前没有任何值 - null:表示空缺,即此处应该有一个值,但目前为空 - 对象(object):各种值组成的集合 通常,我们将数值、字符串、布尔值称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。 而将对象称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。至于undefined和null,一般将它们看成两个特殊值 > 内存中一共分为几种对象:1.变量 2.DOM对象 3.常量 4.自定义对象 <br/> ## **3.2.3 如何判断js中的数据类型** typeof、instanceof、 constructor、 prototype方法比较 ~~~js 如何判断js中的类型呢,先举几个例子: var a = "i am string."; var b = 222; var c= [1,2,3]; var d = new Date(); var e = function(){alert(111);}; var f = function(){this.name="22";}; ~~~ - 最常见的判断方法:typeof ~~~js alert(typeof a) ------------> string alert(typeof b) ------------> number alert(typeof c) ------------> object alert(typeof d) ------------> object alert(typeof e) ------------> function alert(typeof f) ------------> function 其中typeof返回的类型都是字符串形式,需注意,例如: alert(typeof a == "string") -------------> true alert(typeof a == String) ---------------> false 另外typeof可以判断function的类型;在判断除Object类型的对象时比较方便。 ~~~ - 判断已知对象类型的方法:instanceof ~~~js alert(c instanceof Array) ---------------> true alert(d instanceof Date) ---------------> true alert(f instanceof Function) ------------> true alert(f instanceof function) ------------> false 注意:instanceof后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。 ~~~ - 根据对象的constructor判断:constructor ~~~js alert(c.constructor === Array) ----------> true alert(d.constructor === Date) -----------> true alert(e.constructor === Function) -------> true 注意: constructor 在类继承时会出错 例子: function A(){}; function B(){}; A.prototype = new B(); //A继承自B var aObj = new A(); alert(aobj.constructor === B) -----------> true; alert(aobj.constructor === A) -----------> false; 而instanceof方法不会出现该问题,对象直接继承和间接继承的都会报true: alert(aobj instanceof B) ----------------> true; alert(aobj instanceof A) ----------------> true; 言归正传,解决construtor的问题通常是让对象的constructor手动指向自己: aobj.constructor = A; //将自己的类赋值给对象的constructor属性 alert(aobj.constructor === A) -----------> true; alert(aobj.constructor === B) -----------> false; //基类不会报true了; ~~~ - 通用但很繁琐的方法: prototype ~~~js alert(Object.prototype.toString.call(a) === ‘[object String]’) ------> true; alert(Object.prototype.toString.call(b) === ‘[object Number]’) ------> true; alert(Object.prototype.toString.call(c) === ‘[object Array]’) -------> true; alert(Object.prototype.toString.call(d) === ‘[object Date]’) -------> true; alert(Object.prototype.toString.call(e) === ‘[object Function]’) ---> true; alert(Object.prototype.toString.call(f) === ‘[object Function]’) ---> true; 大小写不能写错,比较麻烦,但胜在通用。 通常情况下用typeof判断就可以了,遇到预知Object类型的情况可以选用instanceof或constructor方法 ~~~ <br/> ## **3.2.4 数据类型转换** - **转换函数** - `toString()` 转换为字符串,在JavaScript中所有数据类型都可以转换为`string`类型 - `parseInt()`解析出一个`string`或者`number`类型的整数部分,如果没有可以转换的部分,则返回`NaN`(`not a number`) ~~~js var n1 = "12"; var n2 = "23hello"; var n3 = "hello"; parseInt(n1); //12 parseInt(n2); //23 parseInt(n3); //NaN ~~~ - parseFloat()解析出一个`string`的浮点数部分,如果没有可以转换的部分,则返回`NaN`(not a number) ~~~js var n1 = "1.2.3"; var n2 = "1.2hello" var n3 = "hello" parseFloat(n1); //1.2 parseFloat(n2); //1.2 parseFloat(n3); //NaN ~~~ - ##### **强制类型转换** - ##### `Boolean(value)`- 把给定的值转换成`Boolean`型 - ##### `Number(value)`-把给定的值转换成数字(可以是整数或浮点数) - ##### `String(value)`- 把给定的值转换成字符串 - ##### **隐式转换** - 数字+字符串:数字转换为字符串 console.log(12+"12"); //1212 - 数字+布尔值:true转换为1,false转换为0 console.log(12+true); //13 - 字符串+布尔值:布尔值转换为true或false console.log("hello"+true); //hellotrue - 布尔值+布尔值 console.log(true+true); //2 - **null和undefined** undefined 表示一种未知状态,声明了但没有初始化的变量,变量的值时一个未知状态。访问不存在的属性或对象window.xxx)方法没有明确返回值时,返回值是一个undefined.当对未声明的变量应用typeof运算符时,显示为undefined。 null表示尚未存在的对象,null是一个有特殊意义的值。可以为变量赋值为null,此时变量的值为“已知状态”(不是undefined),即null。(用来初始化变量,清除变量内容,释放内存) > undefined==null //结果为true,但含义不同。 > undefined===null //false,两者类型不一致,前者为“undefined”,后者为“object” <br/> #### 3.2.5 **运算符** 1.算术运算符(+, -, *, /, %, ++, --) - 字符串和数字相加的情况: - 左右都是数字:数字相加 - 左右有一个字符串:字符串拼接 - 左右边有一个null:null看做0 - 左右边有一个undefined:结果是NAN(not a number) 2.赋值运算符(=, -=, +=, *=, /=, %=) 3.比较运算符(\==, ===, !=, >, <, >=, <=) > 先执行表达式计算再赋值 > \==和!=在比较之前首先让双方的值做隐士类型转换,===不转换 4.逻辑运算符(||, &&, !) - || 在js中和PHP中是不一样的 js中返回逻辑或的左边或右边的一个结果;PHP返回||或出来以后的结果即:true false > 特殊性(注意):一定要记住(这个特性和其他编程语言不一样):在js里返回不是布尔值 > > || 短路运算,第一个条件为真,后面不执行 - &&把表达式最后一个值返回(注意这里) 条件运算符`(表达式1?表达式2:表达式3)`三元运算符 ==表达式1?表达式2:表达式3==,表达式1为真,返回表达式2,否则返回表达式3 三元运算符可以多层次嵌套使用 - **在js中,有四种被认为是非**: - `undefined` - `null` - `false` - `0` 例子:`var age = prompt("温馨提示:","请输入您的年龄")||0` 当点击取消的时候,如果出现`undefined` `null` `fasle` `0` 表示非的逻辑 那么`||`就会过滤,取右边的值`0` <br/> ## 3.2.6循环 >[info]console.log调试程序,开发中大量使用这个 而不用`alert` - **js的断点调试方法:** 1. 运行程序,按F12键或者右键鼠标找到“检查”网页 2. 在弹出的窗体选择sources,点开源代码,在想要设置断点的地方的左边代码行单击设置断点 3. 然后要刷新一下页面,页面标题处于“圆圈”状态,表明进入调试模式 4. 拉开最右边的窗体,找到“watch”,可以添加想要检测的变量。 - 条件结构 if if...else if...else if...else 当通过判断返回某个值的时候,优先使用三元表达式 当通过判断执行N段逻辑代码的时候,只能用条件结构 - switch switch case break default 条件 判断 退出 默认 - a.只要匹配上一个case,那么它下面的所有的case都会执行包括default - b.break的意思跳出当前结构 - for for循环有三个要素 - a.循环变量 - b.判断(循环体) - c.改变循环变量 > continue 结束本次循环,继续下一次循环,当前这次循环不做,直接做下面的 > break 跳出本层循环(只跳出一层) - **while/do...while 没有谁好谁坏 只有适应场景不同** - 比如:先吃饭 在买单 do..while 用户体验高 有风险 扫雷游戏也是先体验 在问是否退出 提高体验 - 比如:先买单 在吃饭 while 用户体验不高 > 一般情况下,如果条件判断是数字的比较`== <>`,for循环优先. > 如果是非数值相关的比较循环,while优先 <br/> ## 3.2.7 Object对象 1.JS对象 ​ JS对象有内置对象,宿主对象(JS运行环境提供的对象 BOM DOM)和用户自定义对象,自定义对象通过new关键字来创建,之后内存会为对象开辟一个新的内存空间,位于堆(heap)里面; for...in 语句循环遍历对象的属性。 new关键字代表的是新开辟一块内存空间,没有被引用的内存空间,会在适当的时候被销毁 以下两句代码含义等同 - var person = new Object(); - var person = {}; 访问对象的属性除了用 对象引用`.属性 key`以外,还可以使用对象引用`[属性key]` ~~~js <body> <!--prototype 属性允许您为对象构造器添加新属性:--> <script type="text/javascript"> function Person(){ name="hello"; age=11; } Person.prototype.nation="中国"; Person.prototype.eyecolor="black"; //构造器可以通过 构造器名.prototype 来拿到,或者添加原型属性/方法 //由Person构造器实例化的对象通过.__proto__ 去拿到或者添加原型属性。 var p1=new Person(); var p2=new Person(); //alert(Person.prototype == p1.__proto__); p1.__proto__.eyecolor="黑色"; //alert(p2.__proto__.eyecolor); /*你也可以直接通过对 象名.属性名 去拿到构造器中已有的原型属性 如果对象本身就有,则直接使用,如果没有,对象会自动向上查找(构造器) 如果最后构造器中也没有,才会返回undefined*/ //alert(p1.nation); alert(p1.hhh+"没找到此属性"); //var arr=[1,2,3,5]; var arr=new Array(); arr[0]=1; arr[1]=2; arr[2]=3; for (var s in arr) { //此时s就代表arr数组的下标 alert(arr[s]); //通过arr[下标]就可以得到数组的元素值 } </script> </body> ~~~ <br/> 2.new 原理详细解析 ------ - 无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个`prototype`属性,这个属性指向函数的原型对象。 - 在默认情况下,所有原型对象都会自动获得一个`constructor`(构造函数)属性,这个属性包含一个指向`prototype`属性所在函数的指针(就是指向新创建的函数)。 - 通过这个构造函数(原型对象的构造函数),可以继续为原型对象添加其他属性和方法。 - >当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。`ECMA-262`第5版管这个指针叫 `[[Prototype]]`。脚本中没有标准的方式访问`[[Prototype]]`,但`Firefox`、`Safari`和`Chrome`在每个对象上都支持一个属性`__proto__`;而在其他实现中,这个属性对脚本是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例和构造函数的原型对象之间,而不是存在于实例和构造函数之间 3.new创建对象的步骤 ------ - 创建一个新的对象 - 将构造函数的作用域赋给新对象 - 执行构造函数的代码,为这个新对象添加属性 - 返回新对象 **4.使用工厂方法创建对象** ~~~js 使用工厂方法创建对象,通过该方法可以大批量的创建对象 function createPerson(name , age ,gender){ //创建一个新的对象 var obj = new Object(); //向对象中添加属性 obj.name = name; obj.age = age; obj.gender = gender; obj.sayName = function(){ alert(this.name); }; //将新的对象返回 return obj; } var obj2 = createPerson("猪八戒",28,"男"); var obj3 = createPerson("白骨精",16,"女"); var obj4 = createPerson("蜘蛛精",18,"女"); /* * 使用工厂方法创建的对象,使用的构造函数都是Object * 所以创建的对象都是Object这个类型, * 就导致我们无法区分出多种不同类型的对象 */ ~~~ **5.构造器** ~~~js <script type="text/javascript"> //构造器constructor function person(name,age,sex){ this.name=name; this.age=age; this.sex=sex; this.work=function () { alert("人都要工作"); }; } var tom=new person("tom",23,"男"); var bill=new person("bill",25,"男"); var jessie=new person("jessie",20,"女"); //tom instanceof person 表示判断左边的对象是否属于右边的类 alert(tom instanceof person); //true </script> ~~~