本文共 8477 字,大约阅读时间需要 28 分钟。
在加载网页时,用户会先看到页面的内容,而如果js要加载的东西过多时,页面并不会显示内容,而是空白的这样用户体验会大打折扣,所以这里可以在 script 标签内添加属性来异步完成加载 JavaScript 。
有些 js 代码中会调用 HTML 代码中 id 对应的元素,但是HTML 页面加载是从上到下的,这时如果 js 代码中要用到的话,就需要写到 HTML 的尾部,这里也可以在 script 标签内添加属性来延迟执行 js 文件。
var a="3.1415926535";var b = a - 2;var c = a + 2;alert(b+"\n"+c);
乍一看 b = 1.1415926535,c = 5.1415926535,我们来看输出结果:
字符串不支持减法,所以 a 变量被改变数据类型为数值类型,执行 a- 2=1.14159
但是字符串支持加法运算,加法作为连字符,所以系统吧 c 变量变为字符串,连了起来 c = a+2=......2
//定义全局变量,这里不管用不用var都是全局变量var test="全局变量";function myFun(){ //在函数内的不使用var定义的变量为全局变量 age = 20 //在函数内使用var定义的变量为局部变量 var isMale = true;}myFun();alert(test +"\n" + age);alser(isMale);
如果同名,则局部变量将会覆盖全局变量
var isMale="全局变量";function myFun(){ var isMale ="局部变量"; alert(isMale);}myFun();alert(isMale);
第一次输出为“局部变量”第二次输出为“全局变量”
下面这样会覆盖掉
var isMale="全局变量";function myFun(){ isMale ="局部变量"; alert(isMale);}myFun();alert(isMale);
第一次输出为“局部变量”第二次输出为“局部变量”
补充:
var 定义变量没有块的概念
let 定义变量,有作用域,即块的概念
var scope="全局变量";function test(){ document.writeln(scope + ""); //定义scpoe局部变量,其作用范围为整个函数内 let scope = "局部变量"; document.writeln(scope + "")}test();
输出结果:
JavaScript的变量提升机制,指的是变量声明总是会被解释器“提升”到函数体顶部
(变量提升只是提升变量声明的部分,并不会提升变量赋值部分)
同理下面代码:
var x=100;var y=200;function foo(){ document.writeln(x + ""); document.writeln(y + ""); if(false){ var x=1; } return; var y=2;}foo();
按理说 x=1,与y=2不可能获得执行机会,而且定义了全局变量 x=100,y=200 ,但是由于变量提升机制输出结果为:
这就是只提升了函数的声明,并没有给它赋值,所以会显示undefined。
alert("浏览器版本为:" + navigator.appVersion);
同一个数组中的数组元素可以有不同的数据类型
var a = [3 ,5 ,23];var b = [];var c = new Array();b[0]='hello';b[1]=6;c[5]=true;c[7]=null;alert(a + "\n" + b +"\n" +c + "\na数组的长度:" + a.length + "\nb数组的长度:" + b.length + "\nc数组的长度:" + c.length);
var stack = [];//将数组当栈使用//入栈stack.push("孙悟空");stack.push("猪八戒");stack.push("白骨精");//出栈console.log(stack.pop());console.log(stack.pop());console.log(stack.pop());//将数组当队列使用var queue = [];//入队列queue.unshift("孙悟空");queue.unshift("猪八戒");queue.unshift("白骨精");//出队列console.log(queue.shift());console.log(queue.shift());console.log(queue.shift());
不难发现,栈和队列的输出结果竟然是一致的。
解释:
push方法是在尾部插入元素
pop是把数组尾部的元素弹出来
unshift是在头部插入元素
shift是把数组头部的元素弹出来
所以上面代码中的进出:
stack = ["孙悟空","猪八戒","白骨精"];//pop弹出尾部元素//所以顺序是:白骨精、猪八戒、孙悟空queue = ["白骨精","猪八戒","孙悟空"];//shift弹出头部元素//所以顺序是:白骨精、猪八戒、孙悟空
以上,所以想实现真正的队列和栈需要两者灵活配合使用
concat()为数组添加元素
reverse();反转数组
join()将多个元素用定界符拼接在一起
slice()截取数组
sort()排序
splice()截取追加
var a = ["html",2,"yeeku"];var f = [4,5,6,7,8];console.log(a.concat(4,5));console.log(a.concat([4,5]));console.log(a.concat(f,[6,7]));console.log("-----------------------------------------")var b = ["html",20,"is",99,"good"];console.log(b.join());console.log(b.join("+"));console.log(b.join("冲冲冲"));console.log("-----------------------------------------")var c = ["html","css","jquery","bootstrap"];c.reverse();console.log(c);console.log(c.sort());console.log("-----------------------------------------")var d = ["yeeku","leegang","crazyit","fkit","charlie"];console.log(d.slice(3));console.log(d.slice(2,4));console.log(d.slice(1,-2));console.log(d.slice(-3,-2));console.log("-----------------------------------------")var e = ["yeeku","leegang","crazyit","fkit","charlie"];console.log(e.splice(3));console.log(e.splice(1,1));console.log(e.splice(0,1,20,30,40));console.log(e);
注意:
对于sort函数
默认形式:c.sort();
默认升序排序
我们可以通过给参数,来调整升序还是降序
但是必须是函数
var c = [1,9,2,7,6,1,5,3];c.sort(function(c,b){ return b-c;});console.log(c);
即如果数组中第一个大于第二个数,则降序,否则升序。
var a=b=c=d=e=f=7;
try{ for (var i=0;i<10;i++){ document.writeln(i + ''); if(i>4){ throw new Error('用户自定义异常') } }}catch(e){ document.writeln('系统出现异常' + e.message + '');}finally{ document.writeln('系统的finally块');}
for(propName in navigator){ document.write('属性'+propName+'的值是:'+navigator[propName]); document.write("");}
outer:for(var i = 0;i < 5; i++){ for(var j = 0;j < 5 ;j++){ document.writeln('j的值为:'+j); if(j>=2)break outer; document.writeln('i的值为:' + i); document.writeln(''); }}
执行结果:
hello('zkm');function hello(name){ alert('你好,'+name)}
function hello(name){ if(typeof name == 'string'){ return name + ',你好!'; } return '只能输入字符串!';}alert(hello('zkm'));
var f = function(name){ document.writeln('匿名函数'); document.writeln('你好'+name);};f('zkm');
比如输出不加 “()”的hello
var hello = function(name){ return name + ",你好!";}alert("hello是否为Function对象:" + (hello instanceof Function) + "\nhello是否为Object对象:" + (hello instanceof Object));alert(hello);
执行结果:
加上 “()”的hello 即 hello();
var hello = function(name){ return name + ",你好!";}alert("hello是否为Function对象:" + (hello instanceof Function) + "\nhello是否为Object对象:" + (hello instanceof Object));alert(hello());
执行结果:
function Person(name,age){ this.name = name; this.age = age; this.info = function(){ document.writeln("我的名字是:" + this.name + ""); document.writeln("我的年纪是:" + this.age + ""); }}var p = new Person('zkm',29);p.info();
执行结果:
with(window.open()){ document.writeln("这是一个弹出的新网页!");}
执行结果:
var p = { walk:function(){ for(var i=0;i<5;i++){ document.writeln("慢慢走..."); } }}p.walk();
function hello(name){ document.writeln(name + ",你好! ");}hello('zkm');alert(hello);hello = "冲冲冲";hello("孙悟空");
依次执行的结果:
最后会报错,hello = "冲冲冲"; 把 hello 又定义成了变量,会覆盖掉函数,所以 hello 不在是函数了,而是一个字符串变量。
变量提升与函数提升同时存在时,若变量赋值了,则变量先提升,否则函数提升。
function Person(national, age){ //this修饰的变量为实例属性 this.age = age; //Person修饰的变量为类属性 Person.national = national; //var修饰的变量为局部变量 var bb = 0;}var p1 = new Person('中国',29);document.write("创建一个Person对象");document.writeln("p1的age属性为" + p1.age + "");document.writeln("p1的national属性为" + p1.national + "");document.writeln("通过Person访问静态national属性为" + Person.national + "");document.writeln("p1的bb属性为" + p1.bb + "
");var p2 = new Person('美国',32);document.writeln("创建两个对象之后");document.writeln("p1的age属性为" + p1.age + "");document.writeln("p1的national属性为" + p1.national + "");document.writeln("p2的age属性为" + p2.age + "");document.writeln("p2的national属性为" + p2.national + "");document.writeln("通过Person访问静态national属性为" + Person.national + "");
执行结果:
function Student(grade,subject){ this.grade = grade; Student.subject = subject;}s1 = new Student(5,'Java');with(document){ writeln('s1的grade属性:'+ s1.grade + ""); writeln('s1的subject属性:'+ s1.subject + ""); writeln('Student的subject属性:'+ Student.subject + "");}//为s1对象的subject属性赋值,即为它增加一个subject属性s1.subject = 'Ruby';with(document){ writeln('s1的grade属性:'+ s1.grade + ""); writeln('s1的subject属性:'+ s1.subject + ""); writeln('Student的subject属性:'+ Student.subject + "");}
执行结果:
function Person(name){ this.name = name; this.info = function(){ alert("我的name是:" +this.name); }}var p = new Person("zkm");p.info();window.p.info();//以window对象调用p的info属性//下面这句话就相当于 p.info.call(window) = window.info()//所以 name 就调用的是window下的namep.info.call(window);
执行结果:
前两次:
最后一次:
但是当我们定义了 var name ="ccc";
前两次:
最后一次:
这是直接输出的window下的name
但是当我们删除了 var name ="ccc";
他还是会输出这个,清缓存也没用,把这些函数里的name换成另一个比如iname他就又正常了,我很不解!!!!
function Dog(name ,age ,bark){ this.name = name ; this.age = age; this.bark = bark; this.info = function(){ return this.name + "的年龄为:" + this.age + "它的叫声:" + this.bark; }}var dog = new Dog("旺财",3,"汪汪,汪汪,...");function Cat(name,age){ this.name = name; this.age = age;}var cat = new Cat("Kitty",2);alert(dog.info.call(cat));
最后一句代码:通过 cat 这个对象,去调用dog的info方法
执行结果:
function Dog(name,age,brak){ this.name = name; this.age = age; this.brak = brak;}var dog = new Dog("ccc");alert(dog.age)
执行结果:
undefined
全局函数会被提升到 script 的顶端,而匿名函数只会提升被赋值的变量,而不会提升函数的定义
变量如果赋值则,优先级大于函数,否则小于函数
而函数也要考虑是命名函数,还是匿名函数,命名函数按照规则没问题,而匿名函数需要特殊看待。
function a(){ } var a; console.log(a); //输出代码 var b; function b(){ } console.log(b); //输出代码 var c = 1; function c(){ } console.log(c); //输出1 function d(){ } var d = 1; console.log(d); //输出1
转载地址:http://mwprn.baihongyu.com/