JS学习研究
//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 匹配非字母和数字及_
// 字符类:空白字符
// 元字符/元符号匹配情况
//\0 匹配null 字符
//\b 匹配空格字符
//\f 匹配进纸字符
//\n 匹配换行符
//\r 匹配回车字符
//\t 匹配制表符
//\s 匹配空白字符、空格、制表符和换行符
//\S 匹配非空白字符
// 字符类:锚字符
// 元字符/元符号匹配情况
// ^ 行首匹配
// $ 行尾匹配
//\A 只有匹配字符串开始处
//\b 匹配单词边界,词在[]内时无效
//\B 匹配非单词边界
//\G 匹配当前搜索的开始位置
//\Z 匹配字符串结束处或行尾
//\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\n2.google\n3.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;
//}
JS学习研究的更多相关文章
- BigPipe学习研究
BigPipe学习研究 from: http://www.searchtb.com/2011/04/an-introduction-to-bigpipe.html 1. 技术背景 FaceBook ...
- 数据可视化的优秀入门书籍有哪些,D3.js 学习资源汇总
习·D3.js 学习资源汇总 除了D3.js自身以外,许多可视化工具包都是基于D3开发的,所以对D3的学习就显得很重要了,当然如果已经有了Javascript的经验,学起来也会不费力些. Github ...
- 我的three.js学习记录(二)
通过上一篇文章我的three.js学习记录(一)基本上是入门了three.js,但是这不够3D,这次我希望能把之前做的demo弄出来,然后通过例子来分析操作步骤. 1. 示例 上图是之前做的一个dem ...
- Three.js 学习笔记(1)--坐标体系和旋转
前言 JavaScript 3D library The aim of the project is to create an easy to use, lightweight, 3D library ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- js学习之变量、作用域和内存问题
js学习之变量.作用域和内存问题 标签(空格分隔): javascript 变量 1.基本类型和引用类型: 基本类型值:Undefined, Null, Boolean, Number, String ...
- 【Knockout.js 学习体验之旅】(3)模板绑定
本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(2)花式捆绑
本文是[Knockout.js 学习体验之旅]系列文章的第2篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
随机推荐
- 温故知新-快速理解zookeeper功能&应用&选举机制
文章目录 zookeeper简介 什么是zookeeper zookeeper应用场景 zookeeper特点 zookeeper的角色 zookeeper的数据模型 节点数据结构 节点类型 zook ...
- 是时候拥抱.NET CORE了
微软和社区已经做了大量艰苦的工作,使.net core成为市场上具有竞争力的框架,帮助开发人员快速开发具有最佳性能和可扩展性的强大应用程序.做的最棒的事情使.net framework开发人员不需要任 ...
- Windows环境下PHP安装pthreads多线程扩展
一.判断PHP是ts还是nts版 通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说应该是ts版,否则是nts版. ...
- mysql where与 having的区别
where是针对磁盘的数据文件,having是针对存在内存的结果集的筛选. 例如: select name ,(xxx - xxx) as a from table where a > 10; ...
- Codeblocks 解决界面模糊的方法
之前用16.01不愿意升17.12的原因就是升级后界面变得非常模糊感觉很难看,找了个方法把这个问题解决了,这个方法能解决绝大多数软件打开后界面模糊的问题 (DEV模糊也能解决). 1.安装软件后桌面会 ...
- Quartz.Net系列(四):Quartz五大构件(Scheduler,Job,Trigger,ThreadPool、JobStore)之ThreadPool、JobStore解析
整体示意图: 1.DefaultThreadPool 如果不存在PropertyThreadPoolType,那么就使用DefaultThreadPool var threadPoolTypeStri ...
- flink实时数仓从入门到实战
第一章.flink实时数仓入门 一.依赖 <!--Licensed to the Apache Software Foundation (ASF) under oneor more contri ...
- mysql字符串类型(set类型)
集合 set 不定想项选 类似于 enum枚举,在定义时,也需要指定其已有值! 与字符串相比,优势是: 1, 也是采用 整数进行管理的!采用位运算,从第一位开始为1,逐一x2! 2, 每个集合类型8 ...
- CSS文本相关之水平排列[4]
在正常流中,文本都是从左往右.自上而下排列显示,如果想要改变排列方向的话,可以通过CSS属性来改变. text-align属性 文本排列(text-align)可改变文本在水平上的方向,但不改变内部的 ...
- 6.kubernetes的GUI资源管理插件-dashboard
目录 1.准备dashboard镜像 2.创建资源配置清单 3.应用资源配置清单 4.查看创建的资源 5.解析域名 6.浏览器访问 7.令牌命令行获取方式 准备dashboard镜像 [root@hd ...