zoukankan      html  css  js  c++  java
  • javascript学习

       //1.undefined 是派生自null的
        //alert(undefined == null);
        //alert(undefined === null);
        ////结果 true false
     
        //2.建议还是养成编码的规范,
        //不要忘记初始化变量。
        //var box;
        //var car = null;
        //alert(typeof box == typeof car)
        //结果false
     
        //var hello = 'Hello World!';
        //var hello2 = Boolean(hello);
        //alert(typeof hello);
        ////String类型
        
        //上面是一种显示转换,属于强制性转换。
        //而实际应用中,还有一种隐式转换。
        //比如,在if 条件语句里面的条件判断,就存在隐式转换。
        //var hello = 'Hello World!';
        //if (hello) {
        //    alert('如果条件为true,就执行我这条!');//结果:true
        //} else {
        //    alert('如果条件为false,就执行我这条!');
        //}
     
        //以下是其他类型转换成Boolean类型规则
        //数据类型转换为true 的值转换为false 的值
        //Boolean true false
        //String 任何非空字符串空字符串
        //Number 任何非零数字值(包括无穷大) 0 和NaN
        //Object 任何对象null
        //Undefined undefined
     
        //要想确定一个数值到底是否超过了规定范围,
        //可以使用isFinite()函数。如果没有超过,
        //返回true,超过了返回false。
     
        //可以通过Number.NaN 得到NaN 值,
        //任何与NaN 进行运算的结果均为NaN,
        //NaN 与自身不相等(NaN 不与任何值相等)。
        //alert(Number.NaN); //NaN
        //alert(NaN+1); //NaN
        //alert(NaN == NaN) //false
     
        //继承
        //function Box() {
        //    this.name = '测试';
        //    this.age = 18;
        //    this.height = 171;
        //}
     
        //function Test() {
        //    this.sex = '男';
        //}
     
        //Test.prototype = new Box();
     
        //var test = new Test();
        
        //alert(test.age);
     
        //function Box(name, age) {
        //    alert("姓名:" + name + "年龄:" + age);
        //}
        //Box("asd", 12);
     
        //function Box(name,age)
        //{
        //    return '你的姓名:' + name + ',年龄' + age;
        //}
        //alert(Box('测试', 18));
     
     
        //function Box(num1,num2) {
        //    return num1 * num2;
        //}
        //var num = Box(15, 15);
        //alert(num);
     
        //function Box(num) {
        //    if (num < 50) {
        //        return num;
        //    }
        //    else {
        //        return 100;
        //    }
        //}
        //alert(Box(10));
        //alert(Box(80));
     
        //function Box() {
        //    return arguments[0] + '|' + arguments[1];//得到每次参数的值
        //}
        //alert(Box(1, 2, 3, 4, 5, 6));//传递参数
     
        //function Box() {
        //    return arguments.length;//得到6
        //}
        //alert(Box(1, 2, 3, 4, 56, 7));
     
        //function box() {
        //    var sum = 0;
        //    if (arguments.length == 0) {
        //        return sum;//如果没有参数就返回0;
        //    }
        //    for (var i = 0; i < arguments.length; i++) {//如果有,则累加
        //        sum = sum + arguments[i];
        //    }
        //    return sum;//返回累加结果
        //}
        //alert(box(2, 6541, 3, 1));
     
        //var box = new Object();
        //box.name='测试name';
        //box.age = 28;
     
        //alert(box['name'])
        //alert(box['age'])
        //delete box.age;//删除属性
        //alert(box['name'])
        //alert(box.age)//undefined
     
        //    var box = [
        //{ //第一个元素是一个对象
        //    name: '李炎恢',
        //    age: 28,
        //    run: function () {
        //        return 'run 了';
        //    }
        //},
        //['马云', '李彦宏', new Object()],//第二个元素是数组
        //'江苏', //第三个元素是字符串
        //25 + 25, //第四个元素是数值
        //new Array(1, 2, 3) //第五个元素是数组
        //    ];
     
     
        //var box = ['李炎恢', 28, '盐城']; //当前数组
        //var box2 = box.slice(1); //box.slice(1,3),2-4 之间的元素
        //alert(box2); //28,盐城
        //alert(box); //当前数组
     
        //splice 中的删除功能:
        //var box = ['李炎恢', 28, '盐城']; //当前数组
        //var box2 = box.splice(0,2); //截取前两个元素
        //alert(box2); //返回截取的元素
        //alert(box); //当前数组被截取的元素被删除
     
        //splice 中的插入功能:
        //var box = ['李炎恢', 28, '盐城']; //当前数组
        //var box2 = box.splice(1, 0, '计算机编程', '江苏'); //没有截取,但插入了两条
        //alert(box2); //在第2 个位置插入两条
        //alert(box); //输出
     
        //splice 中的替换功能:
        //var box = ['李炎恢', 28, '盐城']; //当前数组
        //var box2 = box.splice(1, 1, 100);
        //alert(box2);
        //alert(box);
        
        //Date:
        //var box = new Date(Date.UTC(2011, 11, 5, 15, 13, 16));
        //alert('toString:' + box.toString());
        //alert('toLocaleString:' + box.toLocaleString()); //按本地格式输出
        //PS:这两个方法在不同浏览器显示的效果又不一样,但不用担心,这两个方法只是在
        //调试比较有用,在显示时间和日期上,没什么价值。valueOf()方法显示毫秒数。
     
        //日期格式化方法
        //Date 类型还有一些专门用于将日期格式化为字符串的方法。
        //var box = new Date();
        //alert(box.toDateString()); //以特定的格式显示星期几、月、日和年
        //alert(box.toTimeString()); //以特定的格式显示时、分、秒和时区
        //alert(box.toLocaleDateString()); //以特定地区格式显示星期几、月、日和年
        //alert(box.toLocaleTimeString()); //以特定地区格式显示时、分、秒和时区
        //alert(box.toUTCString()); //以特定的格式显示完整的UTC 日期。
        //alert(box.getTime()); //获取日期的毫秒数,和valueOf()返回一致
        //alert(box.setTime(100)); //以毫秒数设置日期,会改变整个日期
        //alert(box.getFullYear()); //获取四位年份
        //alert(box.setFullYear(2012)); //设置四位年份,返回的是毫秒数
        //alert(box.getMonth()); //获取月份,没指定月份,从0 开始算起
        //alert(box.setMonth(11)); //设置月份
        //alert(box.getDate()); //获取日期
        //alert(box.setDate(8)); //设置日期,返回毫秒数
        //alert(box.getDay()); //返回星期几,0 表示星期日,6 表示星期六
        //alert(box.setDay(2)); //设置星期几
        //alert(box.getHours()); //返回时
        //alert(box.setHours(12)); //设置时
        //alert(box.getMinutes()); //返回分钟
        //alert(box.setMinutes(22)); //设置分钟
        //alert(box.getSeconds()); //返回秒数
        //alert(box.setSeconds(44)); //设置秒数
        //alert(box.getMilliseconds()); //返回毫秒数
        //alert(box.setMilliseconds()); //设置毫秒数
        //alert(box.getTimezoneOffset()); //返回本地时间和UTC 时间相差的分钟数
     
        //alert(/box/i.test('This is a Box!'));
     
        //alert(/box/i.exec('This is a Box!'));
     
        //除了test()和exec()方法,String 对象也提供了4 个使用正则表达式的方法。
        //String 对象中的正则表达式方法
        //方法                    含义
        //match(pattern) 返回pattern 中的子串或null
        //replace(pattern, replacement) 用replacement 替换pattern
        //search(pattern) 返回字符串中pattern 开始位置
        //split(pattern) 返回字符串按指定pattern 拆分的数组
     
        /*使用match 方法获取获取匹配数组*/
        //var pattern = /box/ig;
        //var str = 'This is a Box!,That is a Box too';
        //alert(str.match(pattern));//匹配到两个Box,Box
        //alert(str.match(pattern).length);//获取数组的长度 2
     
        /*使用search来查找匹配数据*/
        //var pattern = /box/ig;
        //var str = "This is a Box!,That is Box too";
        //alert(str.search(pattern));//查找到返回位置,否则返回-1;
        //PS:因为search方法查找到即返回,也就是说无需g全局.
     
        ///*使用replace 替换匹配到的数据*/
        //var pattern = /box/ig;
        //var str = 'This is a Box!,That is a Box too';
        //alert(str.replace(pattern, 'Tom')); //将Box 替换成了Tom
     
        //var pattern = / /ig;
        //var str = 'This is a Box!,That is a Box too';
        //alert(str.split(pattern)); //将空格拆开分组成数组
     
        //RegExp对象的静态属性
        //属性短名        含义
        //input $_ 当前被匹配的字符串
        //lastMatch $& 最后一个匹配字符串
        //lastParen $+ 最后一对圆括号内的匹配子串
        //leftContext $` 最后一次匹配前的子串
        //multiline $* 用于指定是否所有的表达式都用于多行的布尔值
        //rightContext $' 在上次匹配之后的子串
     
        /*使用静态属性*/
        //var pattern = /(g)oogle/ig;
        //var str = 'This is google!';
        //pattern.test(str); //执行一下
        //alert(RegExp.input); //This is google!
        //alert(RegExp.leftContext); //This is
        //alert(RegExp.rightContext); //!
        //alert(RegExp.lastMatch); //google
        //alert(RegExp.lastParen); //g
        //alert(RegExp.multiline); //false
     
        //global Boolean 值,表示g 是否已设置
        //ignoreCase Boolean 值,表示i 是否已设置
        //lastIndex 整数,代表下次匹配将从哪里字符位置开始
        //multiline Boolean 值,表示m 是否已设置
        //Source 正则表达式的源字符串形式
        /*使用实例属性*/
        //var pattern = /google/ig;
        //alert(pattern.global); //true,是否全局了
        //alert(pattern.ignoreCase); //true,是否忽略大小写
        //alert(pattern.multiline); //false,是否支持换行
        //alert(pattern.lastIndex); //0,下次的匹配位置
        //alert(pattern.source); //google,正则表达式的源字符串
        //var pattern = /google/g;
        //var str = 'google google google';
        //pattern.test(str); //google,匹配第一次
        //alert(pattern.lastIndex); //6,第二次匹配的位
     
        //    获取控制
        //    正则表达式元字符是包含特殊含义的字符。它们有一些特殊功能,可以控制匹配模式的
        //    方式。反斜杠后的元字符将失去其特殊含义。
        //    字符类:单个字符和数字
        //    元字符/元符号匹配情况
        //    . 匹配除换行符外的任意字符
        //    [a-z0-9] 匹配括号中的字符集中的任意字符
        //    [^a-z0-9] 匹配任意不在括号中的字符集中的字符
        //d 匹配数字
        //D 匹配非数字,同[^0-9]相同
        //w 匹配字母和数字及_
        //W 匹配非字母和数字及_
        //    字符类:空白字符
        //    元字符/元符号匹配情况
        // 匹配null 字符
        // 匹配空格字符
        //f 匹配进纸字符
        //
     匹配换行符
        //
     匹配回车字符
        //	 匹配制表符
        //s 匹配空白字符、空格、制表符和换行符
        //S 匹配非空白字符
        //    字符类:锚字符
        //    元字符/元符号匹配情况
        //    ^ 行首匹配
        //    $ 行尾匹配
        //A 只有匹配字符串开始处
        // 匹配单词边界,词在[]内时无效
        //B 匹配非单词边界
        //G 匹配当前搜索的开始位置
        // 匹配字符串结束处或行尾
        //z 只匹配字符串结束处
        //    字符类:重复字符
        //    元字符/元符号匹配情况
        //    x? 匹配0 个或1 个x
        //    x* 匹配0 个或任意多个x
        //    x+ 匹配至少一个x
        //    (xyz)+ 匹配至少一个(xyz)
        //    x{m,n} 匹配最少m 个、最多n 个x
        //    字符类:替代字符
        //    元字符/元符号匹配情况
        //    this|where|logo 匹配this 或where 或logo 中任意一个
        //    字符类:记录字符
        //    元字符/元符号匹配情况
        //    (string) 用于反向引用的分组
        //1 或$1 匹配第一个分组中的内容
        //2 或$2 匹配第二个分组中的内容
        //3 或$3 匹配第三个分组中的内容
     
        //var pattem = /[a-z][A-Z]+/;
        //var str = 'gOOGLE';
        //alert(pattem.test(str));
     
        //var pattern = /8(.*)8/;
        //var str = 'This is 8google8';
        //var result = str.replace(pattern, '<strong>$1</strong>'); //得到替换的字符串输出
        //document.write(result);
     
        //      贪婪        惰性
        //      +           +?
        //      ?            ??
        //      *           *?
        //      {n}         {n}?
        //      {n,}        {n,}?
        //      {n,m}       {n,m}?
        
        /*关于贪婪和惰性*/
        //var pattern = /[a-z]+?/; //?号关闭了贪婪匹配,只替换了第一个
        //var str = 'abcdefjhijklmnopqrstuvwxyz';
        //var result = str.replace(pattern, 'xxx');
        //alert(result);
     
        //var pattern = /8(.+?)8/g;//禁止了贪婪,开启了全局
        //var str = 'This is 8google8,That is 8google8,There is 8google8';
        //var result = str.replace(pattern, '<strong>$1</strong>');
        //document.write(result);
     
        //var pattern = /8([^8]*)8/g;//另一种禁止贪婪
        //var str = 'This is 8google8,That is 8google8,There is 8google8';
        //var result = str.replace(pattern, '<strong>$1</strong>');
        //document.write(result);
     
     
        /*使用exec 返回数组*/
        //var pattern = /^[a-z]+s[0-9]{4}$/i;
        //var str = 'google 2012';
        //alert(pattern.exec(str)); //返回整个字符串
        //var pattern = /^[a-z]+/i; //只匹配字母
        //var str = 'google 2012';
        //alert(pattern.exec(str)); //返回google
     
        //var pattern = /^([a-z]+)s([0-9]{4})$/i; //使用分组
        //var str = 'google 2012';
        //alert(pattern.exec(str)[0]); //google 2012
        //alert(pattern.exec(str)[1]); //google
        //alert(pattern.exec(str)[2]); //2012
     
        ///*捕获性分组和非捕获性分组*/
        //var pattern = /(d+)([a-z])/; //捕获性分组
        //var str = '123abc';
        //alert(pattern.exec(str)); //123a,123,a
     
        //var pattern = /(d+)(?:[a-z])/; //非捕获性分组
        //var str = '123abc';
        //alert(pattern.exec(str));//123a,123
     
        ///*使用分组嵌套*/
        //var pattern = /(A?(B?(C?)))/; //从外往内获取
        //var str = 'ABC';
        //alert(pattern.exec(str)); //ABC,ABC,BC,C
     
        ///*使用前瞻捕获*/
        //var pattern = /(goo(?=gle))/; //goo 后面必须跟着gle 才能捕获
        //var str = 'google';
        //alert(pattern.exec(str)); //goo,goo
     
        ///*使用特殊字符匹配*/
        //var pattern = /.[/b]/; //特殊字符,用符号转义即可
        //var str = '.[/b]';
        //alert(pattern.test(str));//true
        
        ///*使用换行模式*/
        //var pattern = /^d+/mg; //启用了换行模式
        //var str = '1.baidu
    2.google
    3.bing';
        //var result = str.replace(pattern, '#');
        //alert(result);
     
        //1.检查邮政编码
        //var pattern = /[1-9][0-9]{5}/; //共6 位数字,第一位不能为0
        //var str = '224000';
        //alert(pattern.test(str));
     
        //2.检查文件压缩包
        //var pattern = /[w]+.zip|rar|gz/; //w 表示所有数字和字母加下划线
        //var str = '123.zip'; //.表示匹配.,后面是一个选择
        //alert(pattern.test(str));
     
        ////3.删除多余空格
        //var pattern = /s|//w{0,}|//[u4e00-u9fa5]{0,}/g; //g 必须全局,才能全部匹配
        ////var str = '111 222 333';
        //var str = document.documentElement.innerHTML;
        //var result = str.replace(pattern,''); //把空格匹配成无空格
        //document.write(result);
     
        ////4.删除首尾空格
        //var pattern = /^s+/; //强制首
        //var str = ' goo gle ';
        //var result = str.replace(pattern, '');
        //pattern = /s+$/; //强制尾
        //result = result.replace(pattern, '');
        //alert('|' + result + '|');
     
        ////4.删除首尾空格
        //var pattern = /^s*(.+?)s*$/; //使用了非贪婪捕获
        //var str = ' google ';
        //alert('|' + pattern.exec(str)[1] + '|');
     
        //var pattern = /^s*(.+?)s*$/;
        //var str = ' google ';
        //alert('|' + str.replace(pattern, '$1') + '|'); //使用了分组获取
     
        ////1.普通函数声明
        //function box(num1,num2) {
        //    return num1 + num2;
        //}
     
        ////2.使用变量初始化函数
        //var box = function (num1,num2) {
        //    return num1 + num2;
        //}
     
        ////3.使用Function构造函数
        //var box = new Function('num1', 'num2', 'return num1 + num2');
        //PS:第三种方式我们不推荐,因为这种语法会导致解析两次代码(第一次解析常规
        //ECMAScript 代码,第二次是解析传入构造函数中的字符串),从而影响性能。但我们可以通
        //过这种语法来理解"函数是对象,函数名是指针"的概念。
     
     
        ////二.作为值的函数
        //ECMAScript 中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不
        //仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数
        //的结果返回。
        //function box(sumFunction,num) {
        //    return sumFunction(num);//someFunction
        //}
     
        //function sum(num) {
        //    return num *(num+1)/2;
        //}
        //var result = box(sum, 100);//传递函数到另一个函数里
        //alert(result);
     
        ////三.函数内部属性
        //在函数内部,有两个特殊的对象:arguments 和this。arguments 是一个类数组对象,包
        //含着传入函数中的所有参数,主要用途是保存函数参数。但这个对象还有一个名叫callee 的
        //属性,该属性是一个指针,指向拥有这个arguments 对象的函数。
        //function box(num) {
        //    if (num <= 1) {
        //        return 1;
        //    } else {
        //        return num * box(num - 1); //一个简单的的递归
        //    }
        //}
     
        ////对于阶乘函数一般要用到递归算法,所以函数内部一定会调用自身;如果函数名不改变
        ////是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改。为了解决这个问题,我
        ////们可以使用arguments.callee 来代替。
        //function box(num) {
        //    if (num <= 1) {
        //        return 1;
        //    } else {
        //        return num * arguments.callee(num-1);//使用callee 来执行自身
        //    }
        //}
     
        //函数内部另一个特殊对象是this,其行为与Java 和C#中的this 大致相似。换句话说,
        //this 引用的是函数据以执行操作的对象,或者说函数调用语句所处的那个作用域。PS:当在
        //全局作用域中调用函数时,this 对象引用的就是window。
        //便于理解的改写例子
        //window.color = '红色的'; //全局的,或者var color = '红色的';也行
        //alert(this.color); //打印全局的color
        //var box = {
        //    color : '蓝色的', //局部的color
        //    sayColor : function () {
        //        alert(this.color); //此时的this 只能box 里的color
        //    }
        //};
        //box.sayColor(); //打印局部的color
        //alert(this.color); //还是全局的
     
        ////引用教材的原版例子
        //window.color = '红色的'; //或者var color = '红色的';也行
        //var box = {
        //    color: '蓝色的'
        //};
        //function sayColor() {
        //    alert(this.color); //这里第一次在外面,第二次在box 里面
        //}
        //sayColor();
        //box.sayColor = sayColor; //把函数复制到box 对象里,成为了方法
        //box.sayColor();
     
        ////对于prototype 属性,它是保存所有实例方法的真正所在,也就是原型。这个属性,
        ////我们将在面向对象一章详细介绍。而prototype 下有两个方法:apply()和call(),每个函数都
        ////包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等
        ////于设置函数体内this 对象的值。
     
        //function box(num1,num2) {
        //    return num1 + num2;//原函数
        //}
     
        //function sayBox(num1,num2) {
        //    return box.apply(this, [num1, num2]);//this表示作用域,这里是window
        //}                                        //[]表示box所需要的参数
     
        //function sayBox2(num1,num2) {
        //    return box.apply(this, arguments);//arguments对象表示box所需要的参数
        //}
     
        //alert(sayBox(10, 10));//20
        //alert(sayBox2(10, 10));//20
     
        ////call()方法于apply()方法相同,他们的区别仅仅在于接收参数的方式不同。对于call()方
        ////法而言,第一个参数是作用域,没有变化,变化只是其余的参数都是直接传递给函数的。
        //function box(num1, num2) {
        //    return num1 + num2;
        //}
        //function callBox(num1, num2) {
        //    return box.call(this, num1, num2); //和apply 区别在于后面的传参
        //}
        //alert(callBox(10, 10));//20
     
        ////事实上,传递参数并不是apply()和call()方法真正的用武之地;它们经常使用的地方是
        ////能够扩展函数赖以运行的作用域。
        //var color = '红色的'; //或者window.color = '红色的';也行
        //var box = {
        //    color : '蓝色的'
        //};
        //function sayColor() {
        //    alert(this.color);
        //}
        //sayColor(); //作用域在window
        //sayColor.call(this); //作用域在window
        //sayColor.call(window); //作用域在window
        //sayColor.call(box); //作用域在box,对象冒充
     
        ////这个例子是之前作用域理解的例子修改而成,我们可以发现当我们使用call(box)方法的
        ////时候,sayColor()方法的运行环境已经变成了box 对象里了。
        ////使用call()或者apply()来扩充作用域的最大好处,就是对象不需要与方法发生任何耦合
        ////关系(耦合,就是互相关联的意思,扩展和维护会发生连锁反应)。也就是说,box 对象和
        ////sayColor()方法之间不会有多余的关联操作,比如box.sayColor = sayColor;
     
        ////ECMAScript 中所有函数的参数都是按值传递的,言下之意就是说,参数不会按引用传
        ////递,虽然变量有基本类型和引用类型之分。
        //function box(num) { //按值传递,传递的参数是基本类型
        //    num += 10; //这里的num 是局部变量,全局无效
        //    return num;
        //}
        //var num = 50;
        //var result = box(num);
        //alert(result); //60
        //alert(num); //50
        ////PS:以上的代码中,传递的参数是一个基本类型的值。而函数里的num 是一个局部变
        ////量,和外面的num 没有任何联系。
     
        //下面给出一个参数作为引用类型的例子。
        //function box(obj) { //按值传递,传递的参数是引用类型
        //    obj.name = 'Lee';
        //}
        //var p = new Object();
        //box(p);
        //alert(p.name);
     
        //PS:如果存在按引用传递的话,那么函数里的那个变量将会是全局变量,在外部也可
        //以访问。比如PHP 中,必须在参数前面加上&符号表示按引用传递。而ECMAScript 没有这
        //些,只能是局部变量。可以在PHP 中了解一下。
        //PS:所以按引用传递和传递引用类型是两个不同的概念。
     
        //function box(obj) {
        //    obj.name = 'Lee';
        //    var obj = new Object(); //函数内部又创建了一个对象
        //    obj.name = 'Mr.'; //并没有替换掉原来的obj
        //}
        //var p = new Object();
        //box(p);
        //alert(p.name);
        ////最后得出结论,ECMAScript 函数的参数都将是局部变量,也就是说,没有按引用传递。
     
        ////虽然typeof 运算符在检查基本数据类型的时候非常好用,但检测引用类型的时候,它就
        ////不是那么好用了。通常,我们并不想知道它是不是对象,而是想知道它到底是什么类型的对
        ////象。因为数组也是object,null 也是Object 等等。
        ////这时我们应该采用instanceof 运算符来查看。
        //var box = [1,2,3];
        //alert(box instanceof Array); //是否是数组
        //var box2 = {};
        //alert(box2 instanceof Object); //是否是对象
        //var box3 = /g/;
        //alert(box3 instanceof RegExp); //是否是正则表达式
        //var box4 = new String('Lee');
        //alert(box4 instanceof String); //是否是字符串对象
        ////PS:当使用instanceof 检查基本类型的值时,它会返回false。
     
        ////5.执行环境及作用域
        ////执行环境是JavaScript 中最为重要的一个概念。执行环境定义了变量或函数有权访问的
        ////其他数据,决定了它们各自的行为。
        ////全局执行环境是最外围的执行环境。在Web 浏览器中,全局执行环境被认为是window
        ////对象。因此所有的全局变量和函数都是作为window 对象的属性和方法创建的。
     
        //var box = 'blue'; //声明一个全局变量
        //function setBox() {
        //    alert(box); //全局变量可以在函数里访问
        //}
        //setBox(); //执行函数
     
        ////全局的变量和函数,都是window 对象的属性和方法。
        //var box = 'blue';
        //function setBox() {
        //    alert(window.box); //全局变量即window 的属性
        //}
        //window.setBox(); //全局函数即window 的方法
     
        ////PS:当执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和
        ////函数定义也随之销毁。如果是全局环境下,需要程序执行完毕,或者网页被关闭才会销毁。
        ////PS:每个执行环境都有一个与之关联的变量对象,就好比全局的window 可以调用变量
        ////和属性一样。局部的环境也有一个类似window 的变量对象,环境中定义的所有变量和函数
        ////都保存在这个对象中。(我们无法访问这个变量对象,但解析器会处理数据时后台使用它)
     
        ////函数里的局部作用域里的变量替换全局变量,但作用域仅限在函数体内这个局部环境。
        //var box = 'blue';
        //function setBox() {
        //    var box = 'red'; //这里是局部变量,出来就不认识了
        //    alert(box);
        //}
        //setBox();
        //alert(box); //red blue
     
        ////通过传参,可以替换函数体内的局部变量,但作用域仅限在函数体内这个局部环境。
        //var box = 'blue';
        //function setBox(box) { //通过传参,替换了全局变量
        //    alert(box);
        //}
        //setBox('red');
        //alert(box);
     
        ////函数体内还包含着函数,只有这个函数才可以访问内一层的函数。
        //var box = 'blue';
        //function setBox() {
        //    function setColor() {
        //        var b = 'orange';
        //        alert(box);
        //        alert(b);
        //    }
        //    setColor(); //setColor()的执行环境在setBox()内
        //}
        //setBox();
     
        ////PS:每个函数被调用时都会创建自己的执行环境。当执行到这个函数时,函数的环境
        ////就会被推到环境栈中去执行,而执行后又在环境栈中弹出(退出),把控制权交给上一级的执
        ////行环境。
        ////PS:当代码在一个环境中执行时,就会形成一种叫做作用域链的东西。它的用途是保
        ////证对执行环境中有访问权限的变量和函数进行有序访问。作用域链的前端,就是执行环境的
        ////变量对象。
     
        ////内存问题
        ////JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使
        ////用的内存。其他语言比如C 和C++,必须手工跟踪内存使用情况,适时的释放,否则会造
        ////成很多问题。而JavaScript 则不需要这样,它会自行管理内存分配及无用内存的回收。
        ////JavaScript 最常用的垃圾收集方式是标记清除。垃圾收集器会在运行的时候给存储在内
        ////存中的变量加上标记。然后,它会去掉环境中正在使用变量的标记,而没有被去掉标记的变
        ////量将被视为准备删除的变量。最后,垃圾收集器完成内存清理工作,销毁那些带标记的值并
        ////回收他们所占用的内存空间。
        ////垃圾收集器是周期性运行的,这样会导致整个程序的性能问题。比如IE7 以前的版本,
        ////它的垃圾收集器是根据内存分配量运行的,比如256 个变量就开始运行垃圾收集器,这样,
        ////就不得不频繁地运行,从而降低的性能。
        ////一般来说,确保占用最少的内存可以让页面获得更好的性能。那么优化内存的最佳方案,
        ////就是一旦数据不再有用,那么将其设置为null 来释放引用,这个做法叫做解除引用。这一
        ////做法适用于大多数全局变量和全局对象。
        //var o = {
        //    name : 'Lee'
        //};
        //o = null; //解除对象引用,等待垃圾收集器回收
     
        //var box = document.getElementById('box');
        //alert(box.children.length);
     
        ////关系掩码表
        ////掩码节点关系
        ////1 无关(节点不存在)
        ////2 居前(节点在参考点之前)
        ////4 居后(节点在参考点之后)
        ////8 包含(节点是参考点的祖先)
        ////16 被包含(节点是参考点的后代)
        ////PS:为什么会出现20,那是因为满足了4 和16 两项,最后相加了。为了能让所有浏览
        ////器都可以兼容,我们必须写一个兼容性的函数。
        ////传递参考节点(父节点),和其他节点(子节点)
        //function contains(refNode, otherNode) {
        //    //判断支持contains,并且非Safari 浏览器
        //    if (typeof refNode.contains != 'undefined' &&
        //    !(BrowserDetect.browser == 'Safari' && BrowserDetect.version < 3)) {
        //        return refNode.contains(otherNode);
        //        //判断支持compareDocumentPosition 的浏览器,大于16 就是包含
        //    } else if (typeof refNode.compareDocumentPosition == 'function') {
        //        return !!(refNode.compareDocumentPosition(otherNode) > 16);
        //    } else {
        //        //更低的浏览器兼容,通过递归一个个获取他的父节点是否存在
        //        var node = otherNode.parentNode;
        //        do {
        //            if (node === refNode) {
        //                return true;
        //            } else {
        //                node = node.parentNode;
        //            }
        //        } while (node != null);
        //    }
        //    return false;
        //}
    好好学习,天天向上。
  • 相关阅读:
    什么是跨域?什么是同源策略?如何解决
    安装路由的环境
    react的开发环境
    遍历列表,遍历对象,以及组件
    redux 状态管理工具
    react的钩子函数
    json-server
    react中的setState,受控组件和非受控组件以及组件的传值
    vue中的插槽
    react遍历列表
  • 原文地址:https://www.cnblogs.com/Zhengxue/p/13522644.html
Copyright © 2011-2022 走看看