JS红宝书·读书笔记 -- 上篇

JS红宝书·读书笔记 -- 上篇_第1张图片
JavaScript 高级程序设计

个人博客:https://yeaseonzhang.github.io

花了半个多月的时间,终于又把“JS红宝书”又撸了一遍。

第一次读“JS红宝书”还是2015年初学JS的时候,那时候只是把语法部分读了一遍,还有一些浏览器相关知识做了下了解,大概也就读了半本的样子,
就开始了用JS进行开发了,在成长的道路上遇见了JQuery,当时真的是感觉到JQuery太友好了,慢慢放下了原生开发。

现在呢,更多的时候是在用框架进行开发,越来越觉得自己的JS基础很缺乏,然后就开启了“JS红宝书”二刷之路。

下面就把书中自己觉得重要的、没有掌握的知识整理出来。因为我觉得还是会三刷“JS红宝书”,希望把这本700多页的书越读越薄,勉励。

章节

  • 在HTML中使用JavaScript
  • 基本概念
  • 变量、作用域和内存问题
  • 引用类型
  • 面向对象的程序设计
  • 函数表达式
  • BOM
  • DOM
  • DOM 扩展
  • DOM2 和 DOM3

在HTML中使用JavaScript


async

加载外部脚本文件,通知浏览器立即下载,异步执行。

noscript 元素

noscript标签显示条件:

  • 浏览器不支持脚本
  • 浏览器支持脚本,但是脚本被禁用

基本概念


语法

标识符

  • 第一个字符必须是一个字母、下划线或者一个美元符号
  • 其他字符可以是字母、下划线、美元或者数字

严格模式

支持严格模式的浏览器包括:IE10+、Firefox4+、Safari 5.1+、Opera 12+和Chrome。

数据类型

undefined

对未初始化的变量执行typeof操作会返回undefined值,而对于未声明的变量执行typeof操作同样会返回undefined值。

null

typeof null // -> object

undefined值派生自null值。

console.log(null == undefind)   // -> true

isFinite()

测试一个数值是不是无穷值。

Number.NEGATIVE_INFINITY:负无穷
Number.POSITION_INFINITY:正无穷

NaN

在ECMAScript中,任何数值除以0会返回NaN

isNaN()接受一个参数,确定这个参数是否"不是数值"。

数值转换

Number()

  • 如果是null,返回0
  • 如果是undefined,返回NaN

parseInt()
在ES5 中不支持解析八进制的能力。

parseInt('070');    // -> 70 not 56

通过第二个参数,指定转换基数(进制)默认十进制。

字符串

  • ECMAScript中的字符串是不可变的
  • toString()

在调用数值的toString方法,可以传递一个参数:输出数值的基数。没有toString方法的则返回该值的字面量

var num = 10;
console.log(num.toString(2));   // -> '1010'

object类型

Object类型的属性方法:

  • constructor
  • hasOwnProperty(propertyName)
  • isPrototypeOf(obj)
  • propertyIsEnumerable(propertyName)
  • toLocalString()
  • toString()
  • valueOf()

操作符

  • ++ or --

前置与后置的区别

var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2;   // 21
var num4 = num1 + num2;     // 21

var num5 = 2;
var num6 = 20;
var num7 = num5-- + num6;   // 22
var num8 = num5 + num6;     // 21
  • 一元加操作符用于强制类型转换,隐式Number()效果

for-in 语句

for-in语句是一种精确的迭代语句,可以用来枚举对象的属性。

通过for-in循环输出的属性名的顺序是不可预测的。

如果要迭代的对象的变量值为nullundefinedfor-in语句会抛出错误。ES5更正了这一行为,不再抛出错误,只是不再执行循环体。

建议:在是使用for-in循环之前,先检查对象值是不是null或者undefined

变量、作用域和内存问题


基本类型和引用类型

复制变量值

  • 复制基本类型值,这两个变量相互独立,互不影响。
  • 复制引用类型(对象),值引用是一个指针,改变其中一个对象,会影响另一个对象。

传递参数

function setName(obj) {
    obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"

以上代码中创建一个对象,并将其保存在了变量person 中。然后,这个变量被传递到setName()函数中之后就被复制给了obj。在这个函数部,objperson 引用的是同一个对象。换句话说,即使这个变量是按值传递的,obj 也会按引用来访问同一个对象。于是,当在函数内部为obj 添加name属性后,函数外部的person 也将有所反映;因为person 指向的对象在堆内存中只有一个,而且是全局对象。有很多开发人员错误地认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的。为了证明对象是按值传递的,我们再看一看下面这个经过修改的例子:

function setName(obj) {
    obj.name = "Nicholas";
    obj = new Object();
    obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"

这个例子与前一个例子的唯一区别,就是在setName()函数中添加了两行代码:一行代码为obj重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的name属性。在把person传递给setName()后,其name 属性被设置为"Nicholas"。然后,又将一个新对象赋给变量obj,同时将其name属性设置为"Greg"。如果person 是按引用传递的,那么person 就会自动被修改为指向其name属性值为"Greg"的新对象。但是,当接下来再访问person.name 时,显示的值仍然是"Nicholas"。这说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

检测类型

虽然在检测基本数据类型时typeof 是非常得力的助手,但在检测引用类型的值时,这个操作符的用处不大。通常,我们并不是想知道某个值是对象,而是想知道它是什么类型的对象。为此,ECMAScript提供了instanceof 操作符。

延长作用域

  • try-catch语句中的catch
  • with语句

小结

  • 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
  • 从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;
  • 引用类型的值是对象,保存在堆内存中;
  • 包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;

引用类型


Array类型

检测数组

if (value instanceof Array) {

}

ECMAScript5新增了 Array.isArray()方法

if (Array.isArray(value)) {

}

sort方法

该方法有缺陷,sort()方法会调用每个数组项的toString()转型方法,然后比较字符串进行排序。

var values = [0, 1, 5, 10, 15];
values.sort();
alert(values); //0,1,10,15,5

因此sort()方法接受一个比较函数作为参数。

function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}

var values = [0, 1, 5, 10, 15];
values.sort(compare);
alert(values); //0,1,5,10,15

splice方法

splice方法始终返回一个数组,该数组包含了从原始数组中删除的项。

var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1); // 删除第一项
alert(colors); // green,blue
alert(removed); // red,返回的数组中只包含一项

removed = colors.splice(1, 0, "yellow", "orange"); // 从位置1 开始插入两项
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回的是一个空数组

removed = colors.splice(1, 1, "red", "purple"); // 插入两项,删除一项
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,返回的数组中只包含一项

迭代方法

ECMAScript5为数组定义了5个迭代方法。

  • every(): 对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
  • filter(): 对数组中的每一项运行给定函数,返回该函数会返回true 的项组成的数组。
  • forEach(): 对数组中的每一项运行给定函数。这个方法没有返回值。
  • map(): 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
  • some(): 对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。

归并方法

ECMAScript 5 还新增了两个归并数组的方法。

  • reduce()
  • reduceRight()

reduce()reduceRight()的函数接收4 个参数:前一个值、当前值、项的索引和数组对象。

var values = [1, 2, 3, 4, 5];
var sum = values.reduce((prev, cur, index, array) => {
    return prev + cur;
});
console.log(sum);

RegExp类型

正则表达式中的元字符

( [ { \ ^ $ | ) ? * + . ] }

:匹配元字符必须转义

RegExp 构造函数

接受两个参数: 一个是要匹配的字符串模式,另一个是可选的标志字符串。

var pattern1 = /[bc]at/i;
// 等价于
var pattern2 = new RegExp('[bc]at', 'i');

:由于RegExp构造函数的模式是字符串,所以在某些情况下要对字符串进行双重转义,所有元字符都必须双重转义。例如\n在字符串中被转义为\\n,而在正则表达式字符串中就会变成\\\\n

RegExp实例方法

exex()方法

该方法是专门为捕获组而设计的。exec()接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。返回的数组虽然是Array 的实例,但包含两个额外的属性:indexinput。其中,index 表示匹配项在字符串中的位置,而input 表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)。

var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;

var matches = pattern.exec(text);
alert(matches.index); // 0
alert(matches.input); // "mom and dad and baby"
alert(matches[0]); // "mom and dad and baby"
alert(matches[1]); // " and dad and baby"
aler t(matches[2]); // " and baby"

对于exec()方法而言,即使在模式中设置了全局标志(g),它每次也只会返回一个匹配项。在不设置全局标志的情况下,在同一个字符串上多次调用exec()将始终返回第一个匹配项的信息。而在设置全局标志的情况下,每次调用exec()则都会在字符串中继续查找新匹配项。

test()方法

接受一个字符串参数。在模式与该参数匹配的情况下返回true;否则,返回false

var text = "000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;

if (pattern.test(text)){
    alert("The pattern was matched.");
}

RegExp实例继承的toLocaleString()toString()方法都会返回正则表达式的字面量,与创建正则表达式的方式无关。

var pattern = new RegExp("\\[bc\\]at", "gi");
alert(pattern.toString()); // /\[bc\]at/gi
alert(pattern.toLocaleString()); // /\[bc\]at/gi

Function类型

函数声明与函数表达式

解析器会率先读取函数声明,并使其在执行任何代码之前可用;至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。

// ok
alert(sum(10,10));
function sum(num1, num2){
    return num1 + num2;
}

// unexpected identifier(意外标识符)
alert(sum(10,10));
var sum = function(num1, num2){
    return num1 + num2;
};

:要访问函数的指针而不执行函数的话,必须去掉函数名后的那对圆括号。

函数内部属性

  • arguments
  • this

arguments具有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数。

function factorial(num){
    if (num <=1) {
        return 1;
    } else {
        return num * factorial(num-1)
    }
}

等价于

function factorial(num){
    if (num <=1) {
        return 1;
    } else {
        return num * arguments.callee(num-1)
    }
}

达到一种解耦的效果。

ECMAScript 5也规范了一个函数对象属性:caller(看着很像callee),这个属性中保存着调用当前函数的函数的引用,如果实在全局作用域中调用当前函数,它的值为null

function outer(){
    inner();
}
function inner(){
    alert(inner.caller);
}
outer();

inner.caller指向outer()。为了实现更松散的耦合,也可以通过argument.callee.caller来访问相同的信息。

function outer() {
    inner();
}
function inner() {
    alert(arguments.callee.caller);
}
outer();

:当函数在严格模式下运行时,访问arguments.callee 会导致错误。ECMAScript 5 还定义了arguments.caller属性,但在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是undefined。定义这个属性是为了分清arguments.caller 和函数的caller 属性。以上变化都是为了加强这门语言的安全性,这样第三方代码就不能在相同的环境里窥视其他代码了。
严格模式还有一个限制:不能为函数的caller 属性赋值,否则会导致错误。

函数属性和方法

每个函数都包含两个属性:

  • length: 表示函数希望接收的命名参数的个数
  • prototype: 保存实例方法

每个函数都包含两个非继承而来的方法:

  • apply()
  • call()
    这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this 对象的值。首先,apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中,第二个参数可以是Array 的实例,也可以是arguments对象。
    call()方法与apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。对于call()方法而言,第一个参数是this 值没有变化,变化的是其余参数都直接传递给函数。换句话说,在使用call()方法时,传递给函数的参数必须逐个列举出来。

:在严格模式下,未指定环境对象而调用函数,则this 值不会转型为window。除非明确把函数添加到某个对象或者调用apply()call(),否则this 值将是undefined

在非严格模式下,callapply的第一个参数传递为nullundefined时,函数体内的this会指向默认的宿主对象,在浏览器中则是window

ECMAScript 5定义了一个方法bind(),这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。

基本包装类型

使用new调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。

var value = '25';
var number = Number(value); // 转型函数
console.log(typeof number); // 'number'

var obj = new Number(value); // 构造函数
console.log(typeof obj);    // 'object'

Number类型

Number类型的toString()方法很特别,可以传递一个表示基数的参数。

var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"

String类型

字符方法
  • charAt()
  • charCodeAt()
var stringValue = "hello world";

alert(stringValue.charAt(1)); //"e"
alert(stringValue.charCodeAt(1)); //输出字符编码"101"
字符串操作方法
  • concat()
  • slice()
  • substr()
  • substring()

这些方法对原字符均没有任何影响。

var stringValue = "hello ";
var result = stringValue.concat("world", "!");
alert(result); //"hello world!"

var stringValue = "hello world";
alert(stringValue.slice(3)); //"lo world"
alert(stringValue.substring(3)); //"lo world"
alert(stringValue.substr(3)); //"lo world"
alert(stringValue.slice(3, 7)); //"lo w"
alert(stringValue.substring(3,7)); //"lo w"
alert(stringValue.substr(3, 7)); //"lo worl"

// 参数是负值的情况下,它们的行为就不尽相同了。
// 其中,slice()方法会将传入的负值与字符串的长度相加,
// substr()方法将负的第一个参数加上字符串的长度,而将负的第二个参数转换为0。
// 最后,substring()方法会把所有负值参数都转换为0。
alert(stringValue.slice(-3)); //"rld"
alert(stringValue.substring(-3)); //"hello world"
alert(stringValue.substr(-3)); //"rld"
alert(stringValue.slice(3, -4)); //"lo w"
alert(stringValue.substring(3, -4)); //"hel"
alert(stringValue.substr(3, -4)); //""(空字符串)
字符串位置方法
  • indexOf()
  • lastIndexOf()

两个方法的第二个参数,表示从字符串中哪个位置开始搜索。

trim()方法

ECMAScript 5方法

字符串转换大小写方法
  • toLowerCase()
  • toLocaleLowerCase()
  • toUpperCase()
  • toLocaleUpperCase()
字符串的模式匹配方法
  • match()
  • search()
  • replace()
  • split()

match()方法,在字符串上调用这个方法,本质上和调用RegExpexec()方法相同。match()方法只接受一个参数,要么是一个正则表达式,要么是一个RegExp对象。

var text = 'cat, bat, sat, fat';
var pattern = /.at/;

// 等价于 pattern.exec(text)
var matches = text.match(pattern);
alert(matches.index); //0
alert(matches[0]); //"cat"
alert(pattern.lastIndex); //0

search()方法的参数与match()方法相同,该方法返回字符串中第一个匹配项的索引,没有匹配项返回-1;个人认为serch()就是正则版的indexOf()

var text = "cat, bat, sat, fat";
var pos = text.search(/at/);
aler t(pos); //1

ECMAScript提供了replace()方法,该方法接受两个参数,第一个参数可以是RegExp对象或者是一个字符串,第二个参数可以是一个字符串或者一个函数。

var text = "cat, bat, sat, fat";
var result = text.replace("at", "ond");
alert(result); //"cond, bat, sat, fat"

result = text.replace(/at/g, "ond");
aler t(result); //"cond, bond, sond, fond"

| 字符序列 | 替换文本 |
| : - : | : -- : |
| $$ | $ |
| $& | 匹配整个模式的子字符串。RegExp.lastMatch |
| $' | 匹配子字符串之前的字符串。RegExp.leftContext |
| $` | 匹配的子字符串之后的字符串。 RegExp.rightContext |
| $n | 匹配第n个捕获组的子字符串 n: 0~9 |
| $nn | 匹配第nn个捕获组的子字符串 nn: 01~99 |

var text = "cat, bat, sat, fat";
result = text.replace(/(.at)/g, "word ($1)");
alert(result); //word (cat), word (bat), word (sat), word (fat)

split()方法可以基于指定的分隔符(字符串 or RegExp对象)将一个字符串分割成多个子字符串,并将结构放在一个数组中。可以接受可选的第二个参数,用于指定数组的大小。

var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(","); //["red", "blue", "green", "yellow"]
var colors2 = colorText.split(",", 2); //["red", "blue"]
var colors3 = colorText.split(/[^\,]+/); //["", ",", ",", ",", ""]
localeCompare()方法

比较两个字符串,并返回下列值中的 一个:

  • 如果字符串在字母表中应该排在字符串参数之前,则返回一个负数
  • 如果字符串等于字符串参数,则返回0;
  • 如果字符串在字母表中应该排在字符串参数之后,则返回一个正数
var stringValue = "yellow";
alert(stringValue.localeCompare("brick")); //1
alert(stringValue.localeCompare("yellow")); //0
alert(stringValue.localeCompare("zoo")); //-1
fromCharCode()方法

这个方法的任务是接收一个或多个字符编码,然后将它们转换成一个字符串。相当于charCodeAt()反操作。

alert(String.fromCharCode(104, 101, 108, 108, 111)); //"hello"

Math 对象

  • min()
  • max()
  • ceil()
  • floor()
  • round()
  • random()

面向对象的程序设计

理解对象

属性类型

数据类型
  • [[Configurable]]: 表示能否通过delete删除属性从而重新定义属性,能够修改属性的特性,或者能否把属性修改为访问器属性
  • [[Enumerable]]: 表示能否通过for-in循环返回属性
  • [[Writable]]: 表示能否修改属性的值
  • [[Value]]: 包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。默认值undefined

要修改属性默认的特性,必须使用ECMAScript 5Object.defineProperty()方法。这个方法接受三个参数:属性所在对象,属性名和一个描述符对象。其中描述符对象的属性值必须是:configurableenumerablewritablevalue。设置其中一个或多个。

var person = {};
Object.defineProperty(person, 'name', {
    writable: false,
    value: 'Yeaseon'
});

Object.defineProperty()方法不能对configurable: false的对象进行修改。

访问器属性
  • [[Configurable]]: 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。
  • [[Enumerable]]: 表示能否通过for-in循环返回属性。
  • [[Get]]: 在读取属性时调用的函数,默认undefined
  • [[Set]]: 在写入属性时调用的函数,默认undefined
var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book, "year", {
    get: function(){
        return this._year;
    },
    set: function(newValue){
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2005;
alert(book.edition); //2

读取属性的特性

ECMAScript 5Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符。该方法接收两个参数:属性所在的对象和要读取器描述符的属性名称,返回值是对象。

创建对象

工厂模式

function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");

构造函数模式

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

原型模式

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};

var person1 = new Person();
person1.sayName(); //"Nicholas"

Person.prototype.constructor会指向Personperson1并没有直接连接到构造函数Person

JS红宝书·读书笔记 -- 上篇_第2张图片
  • 可以通过isPrototypeOf()方法来确定对象之间是否存在原型关系。从本质上讲,[[Prototype]]指向调用isPrototypeOf()方法的对象Person.prototype,则会返回true
alert(Person.prototype.isPrototypeOf(person1)); //true

ECMAScript 5增加了Object.getPrototypeOf()方法,该方法返回[[Prototype]]的值。

alert(Object.getPrototypeOf(person1) == Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Nicholas"

: 虽然可以通过对象实例person1访问保存在原型中的值,但却不能重写原型中的值。

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};

var person1 = new Person();
var person2 = new Person();

person1.name = "Greg"; //实质是在实例上增加一个name属性
alert(person1.name); //"Greg"——来自实例
alert(person2.name); //"Nicholas"——来自原型

可以通过delete删除实例属性,从而继续访问原型中的属性。

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var person1 = new Person();

person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例

delete person1.name;
alert(person1.name); //"Nicholas"——来自原型
  • hasOwnProperty()方法可以检测一个属性是不是存在于实例,是则返回true
JS红宝书·读书笔记 -- 上篇_第3张图片
  • in操作符
    (prop in obj)通过in操作符可以判定对象是否有该属性,不论是本身含有还是原型含有,都返回true
    可以通过in配合hasOwnProperty()确定该属性是存在于对象中还是原型中:
function detectProperty(obj, name) {
    if (name in obj) {
        obj.hasOwnProperty(name) ? '在对象中' : '在原型中';
    } else {
        console.log('不含有该属性');
    }
}
  • ECMAScript 5Object.keys()方法可以取得对象上所有可枚举的实例属性。
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"

var p1 = new Person();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"
  • Object.getOwnPropertyNames会得到所有实例属性,不论是否可枚举。
var keys = Object.getOwnPropertyNames(Person.prototype);
alert(keys); //"constructor,name,age,job,sayName"

简化Person.prototype写法:

function Person(){
}
Person.prototype = {
    name : "Nicholas",
    age : 29,
    job: "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};

这样写有一个缺陷,constructor属性则会等于Object,我们需要手动设置constructor

function Person(){
}
Person.prototype = {
    constructor : Person,
    name : "Nicholas",
    age : 29,
    job: "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};

但这同时也会导致constructor[[Enumerable]]特性变成了true,默认情况下是false。再修改下写法:

function Person(){
}
Person.prototype = {
    name : "Nicholas",
    age : 29,
    job : "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};

Object.defineProperty(Person.prototype, "constructor", {
    enumerable: false,
    value: Person
});

原型重写会导致构造函数与最初原型之间的联系切断。

function Person(){
}
var friend = new Person();
Person.prototype = {  //重写
    constructor: Person,
    name : "Nicholas",
    age : 29,
    job : "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};
friend.sayName(); //error
JS红宝书·读书笔记 -- 上篇_第4张图片

结合使用构造函数和原型模式

用构造函数模式定义实例属性,用原型模式定义方法和共享属性。

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Shelby", "Court"];
}
Person.prototype = {
    constructor : Person,
    sayName : function(){
        alert(this.name);
    }
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

继承

构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型的内部指针。

原型链

function SuperType () {
    this.property = true;
}

SuperType.prototype.getSuperValue = function () {
    return this.property;
};

function SubType () {
    this.subproperty = false;
}

SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function () {
    return this.subproperty;
};

var instance = new SubType();
console.log(instance.getSuperValue());  // true
JS红宝书·读书笔记 -- 上篇_第5张图片
instanceof操作符

用来确定原型和实例之间的关系。

alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true

第二种方式就是isPrototypeOf()方法,只要原型链中出现过的原型,都可以说是该原型链所派生的实例的原型。

alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true

函数表达式

由于有声明提升的存在,定义函数不要放在条件表达式中

if (condition) {
    function sayHi () {
        console.log('Hi');
    }
} else {
    function sayHi () {
        console.log('Yo');
    }
}

ECMAScript中属于无效语法,在不同浏览器中修正的做法并不一致。推荐的写法,如下:

var sayHi;

if (condition) {
    sayHi = function () {
        console.log('Hi');
    }
} else {
    sayHi = function () {
        console.log('Yo');
    }
}

这种函数表达式不存在声明提升,所以OK。

递归

函数作用域链

当某个函数被调用时,会创建一个执行环境及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象。在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位...,直到作用域终点的全局执行环境。

闭包

function createFunctions () {
    var result = new Array();
    for (var i=0; i < 10; i++){
        result[i] = function(){
            return i;
        };
    }
    return result;
}
function createFunction () {
    var result = new Array();
    for (var i = 0; i < 10; i++) {
        result[i] = function (num) {
            return function () {
                return num;
            };
        }(i);
    }
    return result;
}

:在闭包中使用this对象可能会导致一些问题。匿名函数的执行环境具有全局性,因此其this对象通常指向window

var name = 'The window';

var obj = {
    name: 'my object',
    getNameFunc: function () {
        return function () {
            return this.nam;
        }
    }
}

console.log(obj.getNameFunc()());  // The Window (非严格模式)

模仿块级作用域

块级作用域

(function () {
    // 这里是块级作用域
})();

BOM


window 对象

全局作用域

抛开全局变量会成为window对象的属性不谈,定义全局变量与在window对象上直接定义属性还是有一点差别:全局变量不能通过delete操作符删除,而直接定义在window对象上的定义的属性可以

窗口位置

获得窗口左边和上边的位置。

var leftPos = (typeof window.screenLeft == 'number') ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == 'number') ? window.screenTop : window.screenY;

Firefox支持screenXscreenY,其他浏览器均支持screenLeftscreenTop

但是还是需要注意一个问题:在IE Opera中,screenLeft screenTop 保存的的是可见区域的距离,也就是我们浏览器中不包含工具栏的区域与屏幕的距离;在ChromeFirefoxSafariscreenYscreenTop返回的是整个浏览器窗口相对于屏幕坐标的值。

窗口大小

IE9+、Firefox、Safari、Opera和Chrome均提供了4个属性innerWidthinnerHeightouterWidthouterHeight

  • IE9+、Safari和Firefox中,outerWidthouterHeight返回浏览器窗口本身的尺寸,而innerWidthinnerHeight则表示该容器中页面视图区的大小(减去边框宽度)
  • Chrome中,inner*outer*返回相同的值,即视口大小而非浏览器窗口的大小。
  • 在IE、Firefox、Safari、Opera和Chrome中,都能通过document.documentElement.clientWidthdocument.documentElement.clientHeight中保存了页面视口信息。

获取页面视口大小

var pageWidth = window.innerWidth,
    pageHeight = window.innerHeight;

if (typeof pageWidth != 'number') {
    if (document.compatMode == 'CSS1Compat') { // 浏览器标准模式
        pageWidth = document.documentElement.clientWidth;
        pageHeight = document.documentElement.clientHeight;
    } else {  // IE6 混杂模式
        pageWidth = document.body.clientWidth;
        pageHeight = document.doby.clientHeight;
    }
}
  • resizeTo()接受浏览器窗口的新宽度和新高度
  • resizeBy()接受新窗口与原窗口的宽度和高度差。

这两个方法可能被浏览器禁用。

导航

如果是浏览器内置的屏蔽程序组织的弹出窗口,那么window.open()很可能会返回null

var newWindow = window.open('https://www.google.com.hk', '_blank');
if (newWindow == null) {
    console.log('The popup was blocked!');
}

如果是浏览器扩展或其他程序组织的弹出窗口,那么window.open()通常会抛出一个错误。

var blocked = false;

try {
    var newWindow = window.open('https://www.google.com.hk', '_blank');
    if (newWindow == null) {
        blocked = true;
    }
} catch (ex) {
    blocked = true;
}

if (blocked) {
    console.log('The popup was blocked');
}

location 对象

location对象的属性

  • hash
  • host
  • hostname:与host不同的是,不带端口号
  • href
  • pathname: 返回URL中的目录和(或)文件名
  • port
  • protocol
  • search:返回URL的查询字符串,这个字符串?开头

navigator 对象

location对象的属性

  • appCodeName: 浏览器的名称,通常都是Mozilla
  • appMinorVersion:此版本信息
  • appName: 完整的浏览器名称
  • appVersion:浏览器的版本
  • buildID:浏览器编译版本
  • cookieEnabled:表示cookie是否可用
  • cpuClass:客户端计算机中使用的CPU类型
  • javaEnabled():表示当前浏览器中是否启用了java
  • language: 浏览器的主语言
  • mimeTypes:浏览器中注册的MIME类型数组
  • onLine:表示浏览器是都连接到因特网
  • oscpu:客户端计算机的操作系统或使用的CPU
  • platform:浏览器所在的系统平台
  • plugins:浏览器中安装的插件信息的数组
  • preference():设置用户的首选项
  • systemLanguage:操作系统的语言
  • userAgent:浏览器的用户代理字符串

DOM


节点层次

Node类型

每个节点都有一个nodeType属性,用于表明节点的类型。

  • Node.ELEMENT_NODE(1)
  • Node.ATTRIBUTE_NODE(2)
  • Node.TEXT_NODE(3)
  • Node.CDATA_SECTION_NODE(4)
  • Node.ENTITY_REFERENCE_NODE(5)
  • Node.ENTITY_NODE(6)
  • Node.PROCESSING_INSTRUCTION_NODE(7)
  • Node.COMMENT_NODE(8)
  • Node.DOCUMENT_NODE(9)
  • Node.DOCUMENT_TYPE_NODE(10)
  • Node.DOCUMENT_FRAGMENT_NODE(11)
  • Node.NOTATION_NODE(12)

为了确保跨浏览器兼容,将nodeType属性与数字值进行比较:

if (someNode.nodeType == 1) {
    console.log('Node is an element');
}
  • nodeName属性
if (someNode.nodeType == 1) {
    var value = someNode.nodeName;  // nodeName的值是元素的标签名
}
节点关系
  • childNodes属性

每个节点都有一个childNodes属性,其中保存着一个NodeList对象,该对象是一种类数组对象。

  • parentNode属性

每个节点都有一个parentNode属性,该属性指向文档树中的父节点。包含在childNodes列表中的每个节点相互都是兄弟节点。使用previousSiblingnextSibling属性,可以访问其他兄弟节点。

:列表中第一个节点的previousSibling属性值为null,同理列表中最后一个节点的nextSibling属性也是null。父节点的firstChildlastChild属性分别指向其childNodes列表中的第一个和最后一个节点。如果不存在则为null

hasChildNodes()方法在节点包含一个或多个子节点的情况下返回true,比查询childNodes.length更简便。

最后一个属性ownerDocument,该属性指向表示整个文档的文档节点(root),直接返回根节点不需要一层层向上回溯。

操作节点
  • appendChild()

用于向childNodes列表的末尾添加一个节点。

var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true

任何DOM节点不可能同时出现在多个位置。

//someNode 有多个子节点
var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode == someNode.firstChild); //false
alert(returnedNode == someNode.lastChild); //true
  • insertBefore()

把节点放在指定位置,该方法接受两个参数:要插入的节点和作为参考的节点。插入节点后,被插入的节点会变成参照节点的前一个兄弟节点。参照节点是null的话,insertBeforeappendChild执行相同的操作,都插入列表末尾。

//插入后成为最后一个子节点
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true

//插入后成为第一个子节点
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
alert(newNode == someNode.firstChild); //true

//插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //true
  • replaceChild()

替换节点,接受两个参数:要插入的节点和要替换的节点。

//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);

//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
  • removeChild()

移除节点,接受一个参数:要被移除的节点。

//移除第一个子节点
var formerFirstChild = someNode.removeChild(someNode.firstChild);

//移除最后一个子节点
var formerLastChild = someNode.removeChild(someNode.lastChild);
  • cloneNode()

复制节点,接受一个布尔值,表示是否深复制。复制后返回的节点没有父节点,可以通过插入等操作手动指定。

var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3(IE < 9)或7(其他浏览器)

var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0

cloneNode方法不会复制DOM节点的js属性。IE存在一个bug,它会复制事件处理程序。

  • normalize()

稍后讨论

以上方法的返回值,都是被操作的节点。

Document类型

Document节点具有下列特征:

  • nodeType的值为9
  • nodeName的值为#document
  • nodeValue的值为null
  • parentNode的值为null
  • ownerDocument的值为null
  • 其子节点可能是一个DocumentType(最多一个)、Element(最多一个)、ProcessingInstructionComment
// 通过`documentElement`属性访问元素
var html = document.documentElement;
// 访问  元素
var body = document.body;
// 
var doctype = document.doctype;
// 
var title = document.title;
// 完整 url
var url = document.URL;
// domain 域名
var domain = document.domain;
// 取得来源页面的URL(也就是导航到这页的页面)
var referrer = document.referrer;
</code></pre> 
 <p>查找元素的方法:</p> 
 <ul> 
  <li><code>document.getElementById()</code></li> 
  <li><code>document.getElementsByTagName()</code></li> 
  <li><code>document.getElementsByName()</code></li> 
 </ul> 
 <p>文档写入:</p> 
 <ul> 
  <li><code>document.write()</code></li> 
  <li> <code>document.writeln()</code>在字符串尾加换行符(\n)</li> 
 </ul> 
 <pre><code><script type="text/javascript">
    document.write("<script type=\"text/javascript\" src=\"file.js\">" + "<\/script>");
</script>
</code></pre> 
 <h4>Element类型</h4> 
 <p><code>Element</code>类型提供了对元素标签名、子节点及特性的访问。</p> 
 <ul> 
  <li> <code>nodeType</code>的值为1</li> 
  <li> <code>nodeName</code>的值为元素的标签名</li> 
  <li> <code>nodeValue</code>的值为<code>null</code> </li> 
  <li> <code>parentNode</code>可能是<code>Document</code>或<code>Element</code> </li> 
  <li>其子节点可能是<code>Element</code>、<code>Text</code>、<code>Comment</code>、<code>ProcessingInstruction</code>、<code>CDATASection</code>或<code>EntityReference</code> </li> 
 </ul> 
 <p>访问元素的标签名,可以使用<code>nodeName</code>属性,也可以使用<code>tagName</code>属性,后者更直观。</p> 
 <pre><code><div id="myDiv"></div>

var div = document.getElementById("myDiv");
alert(div.tagName); //"DIV"
alert(div.tagName == div.nodeName); //true
</code></pre> 
 <p>操作特性的方法:</p> 
 <ul> 
  <li><code>getAttribute()</code></li> 
  <li><code>setAttribute()</code></li> 
  <li><code>removeAttribute()</code></li> 
 </ul> 
 <p><code>attributes</code>属性</p> 
 <p><code>Element</code>类型是使用<code>attributes</code>属性的唯一一个DOM节点属性。<code>attributes</code>属性包含一个<code>NamedNodeMap</code>。元素的每一个特性都由一个<code>Attr</code>节点表示,每个节点都保存在<code>NamedNodeMap</code>对象中。</p> 
 <p><code>NamedNodeMap</code>对象的方法:</p> 
 <ul> 
  <li> <code>getNamedItem(name)</code>:返回<code>nodeName</code>属性等于<code>name</code>的节点</li> 
  <li> <code>removeNamedItem(name)</code>:从列表中移除<code>nodeName</code>属性等于<code>name</code>的节点</li> 
  <li> <code>setNamedItem(node)</code>:向列表中添加节点,以节点的<code>nodeName</code>属性为索引</li> 
  <li> <code>item(pos)</code>:返回位于数字<code>pos</code>位置处的节点</li> 
 </ul> 
 <p><code>attributes</code>属性中包含一系列节点,每个节点的<code>nodeName</code>就是特性的名称,而节点<code>nodeValue</code>就是特性的值。</p> 
 <pre><code>var id = element.attributes.getNamedItem('id').nodeValue;
// 简写
var id = element.attributes['id'].nodeValue;
</code></pre> 
 <p>创建元素<br> <code>document.createElement()</code>方法可以创建新元素,这个方法接受一个参数(标签名)</p> 
 <pre><code>var div = document.createElement('div');
</code></pre> 
 <h4>Text类型</h4> 
 <p>文本节点由<code>Text</code>类型表示,包含的是可以照字面解释的纯文本内容。纯文本中可以包含转义后的HTML字符,但不能包含HTML代码。</p> 
 <ul> 
  <li> <code>nodeType</code>的值为3</li> 
  <li> <code>nodeName</code>的值为<code>#text</code> </li> 
  <li> <code>nodeValue</code>的值为节点所包含的文本</li> 
  <li> <code>parentNode</code>是一个<code>Element</code> </li> 
 </ul> 
 <p>操作节点中的文本:</p> 
 <ul> 
  <li> <code>appendData(text)</code>:将<code>text</code>添加到节点的末尾</li> 
  <li> <code>deleteData(offset, count)</code>:从<code>offset</code>指定的位置开始删除<code>count</code>个字符</li> 
  <li> <code>insertData(offset, text)</code>:在<code>offset</code>指定的位置插入<code>text</code> </li> 
  <li> <code>replaceData(offset, count, text)</code>:用<code>text</code>替换从<code>offset</code>指定的位置开始到<code>offset+count</code>为止的文本</li> 
  <li> <code>splitText(offset)</code>:从<code>offset</code>指定的位置将当前文本分成两个文本节点</li> 
  <li> <code>substringData(offset, count)</code>:提取从<code>offset</code>指定的位置开始到<code>offset+count</code>为止处的字符串。</li> 
 </ul> 
 <p>在向DOM文档中插入文本之前,应该先对其进行<code>HTML</code>编码</p> 
 <p>创建文本节点</p> 
 <ul> 
  <li><code>document.createTextNode()</code></li> 
 </ul> 
 <pre><code>var textNode = document.createTextNode("<strong>Hello</strong> world!");
</code></pre> 
 <h3>DOM 操作技术</h3> 
 <p>使用函数实现加载外部<code>JS</code>文件</p> 
 <pre><code>function loadScript(url) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    document.body.appendChild(script);
}
loadScirpt('xx.js');
</code></pre> 
 <p>IE将<code><script></code>视为一个特殊的元素,不允许DOM访问其子节点。不过可以使用<code><script></code>元素的<code>text</code>属性指定<code>JS</code>代码。</p> 
 <h4>操作表格</h4> 
 <pre><code>// create table
var table = document.createElement('table');
table.border = 1;
table.width = '100%';

// create tbody
var tbody = document.createElement('tbody');
table.appendChild(tbody);

// create row1
var row1 = document.createElement('tr');
tbody.appendChild(row1);

var cell1_1 = document.createElement('td');
cell1_1.appendChild(document.createTextNode('Cell 1,1'));
row1.appendChild(cell1_1);

var cell2_1 = document.createElement('td');
cell2_1.appendChild(document.createTextNode('Cell 2,1'));
row1.appendChild(cell2_1);

// create row2
var row2 = document.createElement('tr');
tbody.appendChild(row2);

var cell1_2 = document.createElement('td');
cell1_2.appendChild(document.createTextNode('Cell 1,2'));
row1.appendChild(cell1_2);

var cell2_2 = document.createElement('td');
cell2_2.appendChild(document.createTextNode('Cell 2,2'));
row1.appendChild(cell2_2);

document.body.appendChild(table);
</code></pre> 
 <h2>DOM 扩展</h2> 
 <hr> 
 <h3>选择符 API</h3> 
 <ul> 
  <li> <code>querySelector()</code>方法</li> 
 </ul> 
 <p><code>querySelector()</code>方法接受一个<strong>CSS</strong>选择符,返回与该模式匹配的<strong>第一个元素</strong>,若没有,返回<code>null</code>。</p> 
 <p>可以通过<code>Document</code>类型调用,也可以通过<code>Element</code>类型调用,后者只会在该元素后代元素的范围内查找匹配的元素。</p> 
 <ul> 
  <li> <code>querySelectorAll()</code>方法</li> 
 </ul> 
 <p><code>querySelectorAll()</code>方法返回的是所有匹配的元素,是一个<code>NodeList</code>实例。</p> 
 <ul> 
  <li> <code>matchesSelector()</code>方法</li> 
 </ul> 
 <p>为<code>Element</code>类型新增的一个方法,接受一个参数<code>CSS</code>选择符,如果调用元素与该选择符匹配,返回<code>true</code>,否则返回<code>false</code>。</p> 
 <h3>元素遍历</h3> 
 <ul> 
  <li> <code>childElementCount</code>:返回子元素(不包含文本节点和注释)的个数</li> 
  <li> <code>firstElementChild</code>:指向第一个子元素</li> 
  <li> <code>lastElementChild</code>:指向最后一个子元素</li> 
  <li> <code>previousElementSibling</code>:指向前一个兄弟元素</li> 
  <li> <code>nextElementSibling</code>:指向后一个兄弟元素</li> 
 </ul> 
 <p>不同于前面的返回<strong>节点</strong>的方法。</p> 
 <pre><code>// 节点版本
var i,
    len,
    child = element.firstChild;
while(child != element.lastChild){
    if (child.nodeType == 1){ //检查是不是元素
        processChild(child);
    }
    child = child.nextSibling;
}
// 元素版本
var i,
    len,
    child = element.firstElementChild;
while(child != element.lastElementChild){
    processChild(child); //已知其是元素
    child = child.nextElementSibling;
}
</code></pre> 
 <h3>HTML5</h3> 
 <ul> 
  <li> <code>getElementsByClassName()</code>方法</li> 
  <li> <code>classList</code>属性,这个属性是新集合类型<code>DOMTokenList</code>的实例。 
   <ul> 
    <li><code>add(value)</code></li> 
    <li><code>contains(value)</code></li> 
    <li><code>remove(value)</code></li> 
    <li><code>toggle(value)</code></li> 
   </ul> </li> 
 </ul> 
 <pre><code>div.classList.remove("user");
</code></pre> 
 <h4>焦点管理</h4> 
 <p><code>document.activeElement</code>属性,始终会引用DOM中前端获得了焦点的元素。</p> 
 <pre><code>var button = document.getElementById("myButton");
button.focus();
alert(document.activeElement === button); //true
</code></pre> 
 <p><code>document.hasFocus()</code>方法,可以确定文档是否获得了焦点。</p> 
 <pre><code>var button = document.getElementById("myButton");
button.focus();
alert(document.hasFocus()); //true
</code></pre> 
 <h4> <code>HTMLDocument</code>的变化</h4> 
 <pre><code>+ `readyState`属性有两个值,`loading`和`complete`
</code></pre> 
 <pre><code>if (document.readyState == 'complete') {
    // 加载完成
}
</code></pre> 
 <h4> <code>document.charset</code>字符集属性</h4> 
 <h4> <code>data-</code>自定义数据属性</h4> 
 <pre><code><div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>

var div = document.getElementById("myDiv");

//取得自定义属性的值
var appId = div.dataset.appId;
var myName = div.dataset.myname;

//设置值
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
</code></pre> 
 <h4> <code>innerHTML</code>属性</h4> 
 <p>在读模式下,<code>innerHTML</code> 属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应<br> 的HTML 标记。在写模式下,<code>innerHTML</code> 会根据指定的值创建新的DOM树,然后用这个DOM树完全<br> 替换调用元素原先的所有子节点</p> 
 <h4> <code>outerHTML</code>属性</h4> 
 <p>在读模式下,<code>outerHTML</code> 返回调用它的元素及所有子节点的HTML 标签。在写模式下,<code>outerHTML</code><br> 会根据指定的HTML 字符串创建新的DOM 子树,然后用这个DOM子树完全替换调用元素。</p> 
 <h4> <code>insertAdjacentHTML()</code>方法</h4> 
 <p>插入元素的新增方法,接受两个参数,插入的位置和要插入的HTML文本,第一个参数的值:</p> 
 <ul> 
  <li><code>'beforebegin'</code></li> 
  <li><code>'afterbegin'</code></li> 
  <li><code>'beforeend'</code></li> 
  <li><code>'afterend'</code></li> 
 </ul> 
 <pre><code>//作为前一个同辈元素插入
element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>");

//作为第一个子元素插入
element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>");

//作为最后一个子元素插入
element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>");

//作为后一个同辈元素插入
element.insertAdjacentHTML("afterend", "<p>Hello world!</p>");
</code></pre> 
 <h4> <code>scrollIntoView()</code>方法</h4> 
 <p><code>scrollIntoView</code>方法可以在所有HTML元素上调用,通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视口中。如果这个方法传入<code>true</code>作为参数,或者不传参数,那么窗口滚动之后就会让调用元素的顶部与视口顶部 尽可能平齐,如果传入<code>false</code>,调用元素会尽可能全部出现在视口中,不过顶部不一定平齐。</p> 
 <pre><code>// 让元素可见
document.form[0].scrollIntoView();
</code></pre> 
 <h3>专有扩展</h3> 
 <h4>插入文本</h4> 
 <ul> 
  <li> <code>innerText</code>属性</li> 
  <li> <code>outerText</code>属性</li> 
 </ul> 
 <h4>滚动</h4> 
 <ul> 
  <li> <code>scrollIntoViewIfNeeded(alignCenter)</code>:只有在当前元素不可见的情况下,才滚动浏览器或窗口或容器元素最终让它可见。如果当前元素在视口中可见,这个方法什么也不做。</li> 
  <li> <code>scrollByLines(lineCount)</code>:将元素的内容滚动指定的行高,<code>lineCount</code>值可以是正值,也可以是负值。</li> 
  <li> <code>scrollByPages(pageCount)</code>:将元素的内容滚动指定的页面高度,具体高度由元素的高度决定。</li> 
 </ul> 
 <p><code>scrollIntoView()</code>和<code>scrollIntoViewIfNeeded()</code>的作用对象是元素的容器,而<code>scrollByLines()</code>和<code>scrollByPages()</code>影响的则是元素自身。</p> 
 <pre><code>//在当前元素不可见的时候,让它进入浏览器的视口
document.images[0].scrollIntoViewIfNeeded();

//将页面主体往回滚动1 页
document.body.scrollByPages(-1);
</code></pre> 
 <h2>DOM2 和 DOM3</h2> 
 <hr> 
 <h3>样式</h3> 
 <h3>元素大小</h3> 
 <h4>偏移量</h4> 
 <ul> 
  <li> <code>offsetHeight</code>:元素在垂直方向上占用的空间大小。包括元素的高度,(可见的)水平滚动条的高度,上边框高度和下边框高度</li> 
  <li> <code>offsetWidth</code>:元素在水平方向上占用的空间大小。包括元素的宽度,(可见的)垂直滚动条的宽度,左边框宽度和右边框宽度</li> 
  <li> <code>offsetLeft</code>:元素的左外边框至包含元素的左内边框之间的像素距离。</li> 
  <li> <code>offsetTop</code>:元素的上外边框至包含元素的上内边框之间的像素距离。</li> 
 </ul> 
 <div class="image-package"> 
  <div class="image-container" style="max-width: 700px; max-height: 387px;"> 
   <div class="image-view"> 
    <a href="http://img.e-com-net.com/image/info10/6c7c4f00f7d143c19930af69c5c2ce64.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info10/6c7c4f00f7d143c19930af69c5c2ce64.jpg" width="650" height="355" alt="JS红宝书·读书笔记 -- 上篇_第6张图片" style="border:1px solid black;"></a> 
   </div> 
  </div> 
  <div class="image-caption"></div> 
 </div> 
 <p>其中,<code>offsetLeft</code>和<code>offsetTop</code>属性与包含元素有关,包含元素的引用保存在<code>offsetParent</code>属性中。<code>offsetParent</code>属性不一定与<code>parentNode</code>的值相等。</p> 
 <pre><code>// 元素上偏移
function getElementLeft (ele) {
    var actualLeft = ele.offsetLeft;
    var current = ele.offsetParent;

    while (current !== null) {
        actualLeft += current.offsetLeft;
        current = current.offsetParent;
    }
    return actualLeft;
}
// 元素左偏移同理
</code></pre> 
 <p>一般来说,页面中所有的元素都被包含在几个<code><div></code>元素中,而这些<code><div></code>元素的<code>offsetParent</code>又是<code><body></code>元素,所以<code>getElementLeft()</code>与<code>getElementTop()</code>会返回与<code>offsetLeft</code>和<code>offsetTop</code>相同的值。</p> 
 <h4>客户区大小</h4> 
 <ul> 
  <li> <code>clientWidth</code>:元素内容区宽度加上左右内边距宽度</li> 
  <li> <code>clientHeight</code>: 元素内容区高度加上上下内边距高度</li> 
 </ul> 
 <div class="image-package"> 
  <div class="image-container" style="max-width: 647px; max-height: 391px;"> 
   <div class="image-view"> 
    <a href="http://img.e-com-net.com/image/info10/740185b44ee64e8793cae11a07c2faca.png" target="_blank"><img src="http://img.e-com-net.com/image/info10/740185b44ee64e8793cae11a07c2faca.png" width="647" height="391" alt="JS红宝书·读书笔记 -- 上篇_第7张图片" style="border:1px solid black;"></a> 
   </div> 
  </div> 
  <div class="image-caption"></div> 
 </div> 
 <pre><code>function getViewport(){
    if (document.compatMode == "BackCompat"){  // IE7之前
            return {
                width: document.body.clientWidth,
                height: document.body.clientHeight
            };
        } else {
            return {
                width: document.documentElement.clientWidth,
                height: document.documentElement.clientHeight
            };
        }
}
</code></pre> 
 <h4>滚动大小</h4> 
 <p><strong>滚动大小</strong>,指的是包含滚动内容的元素的大小。有些元素(<code><html></code>),即使没有执行任何代码也能自动添加滚动条;但另外一些元素,则需要通过<strong>CSS</strong>的<code>overflow</code>属性设置才能滚动。</p> 
 <ul> 
  <li> <code>scrollHeight</code>:在没有滚动条的情况下,元素内容的总高度</li> 
  <li> <code>scrollWidth</code>:在没有滚动条的情况下,元素内容的总宽度</li> 
  <li> <code>scrollLeft</code>:被隐藏在内容区域左侧的像素数,通过设置这个属性可以改变元素的滚动位置</li> 
  <li> <code>scrollTop</code>:被隐藏在内容区域上方的像素数,通过设置这个属性可以改变元素的滚动位置</li> 
 </ul> 
 <div class="image-package"> 
  <div class="image-container" style="max-width: 700px; max-height: 440px;"> 
   <div class="image-view"> 
    <a href="http://img.e-com-net.com/image/info10/051ea3b939944d649bb62c53f43e4adb.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info10/051ea3b939944d649bb62c53f43e4adb.jpg" width="650" height="388" alt="JS红宝书·读书笔记 -- 上篇_第8张图片" style="border:1px solid black;"></a> 
   </div> 
  </div> 
  <div class="image-caption"></div> 
 </div> 
 <p><code>scrollWidth</code>和<code>scrollHeight</code>主要用于确定元素内容的实际大小。</p> 
 <p><code>scrollWidth</code> 和<code>scrollHeight</code> 与<code>clientWidth</code> 和<code>clientHeight</code> 之间的关系?</p> 
 <ul> 
  <li> <strong>Firefox</strong>中这两组属性始终相等,但大小代表的是文档内容区域的实际尺寸,非视口尺寸</li> 
  <li> <strong>Opera Safari Chrome</strong>中这两组属性有区别,其中<code>scrollWidth</code> 和<code>scrollHeight</code> 等于视口大小,而<code>clientWidth</code> 和<code>clientHeight</code> 等于文档内容区域的大小。</li> 
  <li> <strong>IE(在标准模式)</strong>中的这两组属性不相等,其中<code>scrollWidth</code> 和<code>scrollHeight</code> 等于文档内容区域的大小,而<code>clientWidth</code> 和<code>clientHeight</code> 等于视口大小。</li> 
 </ul> 
 <p>通过<code>scrollLeft</code> 和<code>scrollTop</code> 属性既可以确定元素当前滚动的状态,也可以设置元素的滚动位置。在元素尚未被滚动时,这两个属性的值都等于0。如果元素被垂直滚动了,那么<code>scrollTop</code> 的值会大于0,且表示元素上方不可见内容的像素高度。如果元素被水平滚动了,那么<code>scrollLeft</code> 的值会大于0,且表示元素左侧不可见内容的像素宽度。这两个属性都是可以设置的,因此将元素的<code>scrollLeft</code> 和<code>scrollTop</code> 设置为0,就可以重置元素的滚动位置。下面这个函数会检测元素是否位于顶部,如果不是就将其回滚到顶部。</p> 
 <pre><code>function scrollToTop(element){
    if (element.scrollTop != 0){
        element.scrollTop = 0;
    }
}
</code></pre> 
 <h4>确定元素大小</h4> 
 <ul> 
  <li> <code>getBoundingClientRect()</code>方法,会返回一个矩形对象,包含<code>left top right bottom</code>四个属性。这些属性给出了元素在页面中相对于视口的位置。</li> 
 </ul> 
 <h3>遍历</h3> 
 <h4>NodeIterator</h4> 
 <p>可以使用<code>document.createNodeIterator()</code>方法创建它的新实例,接受4个参数。</p> 
 <ul> 
  <li> <code>root</code>:想要作为搜索起点的树中的节点</li> 
  <li> <code>whatToShow</code>:表示要访问哪些节点的数字代码</li> 
  <li> <code>filter</code>:是一个<code>NodeFilter</code>对象,或者一个表示应该接受还是拒绝某种特定节点的函数</li> 
  <li> <code>entityReferenceExpansion</code>:布尔值,表示是否要扩展实体引用。</li> 
 </ul> 
 <p><code>whatToShow</code>这个参数的值以常量形式在<code>NodeFilter</code>类型中定义:</p> 
 <ul> 
  <li><code>NodeFilter.SHOW_ALL</code></li> 
  <li><code>NodeFilter.SHOW_ELEMENT</code></li> 
  <li><code>NodeFilter.SHOW_ATTRIBUTE</code></li> 
  <li><code>NodeFilter.SHOW_TEXT</code></li> 
  <li><code>NodeFilter.SHOW_CDATA_SECTION</code></li> 
  <li><code>NodeFilter.SHOW_ENTITY_REFERENCE</code></li> 
  <li><code>NodeFilter.SHOW_ENTITYE</code></li> 
  <li><code>NodeFilter.SHOW_PROCESSING_INSTRUCTION</code></li> 
  <li><code>NodeFilter.SHOW_COMMENT</code></li> 
  <li><code>NodeFilter.SHOW_DOCUMENT</code></li> 
  <li><code>NodeFilter.SHOW_DOCUMENT_TYPE</code></li> 
  <li><code>NodeFilter.SHOW_DOCUMENT_FRAGMENT</code></li> 
  <li><code>NodeFilter.SHOW_NOTATION</code></li> 
 </ul> 
</article>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1186040233372786688"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(JS红宝书·读书笔记 -- 上篇)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835512920797179904.htm"
                           title="element实现动态路由+面包屑" target="_blank">element实现动态路由+面包屑</a>
                        <span class="text-muted">软件技术NINI</span>
<a class="tag" taget="_blank" href="/search/vue%E6%A1%88%E4%BE%8B/1.htm">vue案例</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>el-breadcrumb是ElementUI组件库中的一个面包屑导航组件,它用于显示当前页面的路径,帮助用户快速理解和导航到应用的各个部分。在Vue.js项目中,如果你已经安装了ElementUI,就可以很方便地使用el-breadcrumb组件。以下是一个基本的使用示例:安装ElementUI(如果你还没有安装的话):你可以通过npm或yarn来安装ElementUI。bash复制代码npmi</div>
                    </li>
                    <li><a href="/article/1835512809883004928.htm"
                           title="10月|愿你的青春不负梦想-读书笔记-01" target="_blank">10月|愿你的青春不负梦想-读书笔记-01</a>
                        <span class="text-muted">Tracy的小书斋</span>

                        <div>本书的作者是俞敏洪,大家都很熟悉他了吧。俞敏洪老师是我行业的领头羊吧,也是我事业上的偶像。本日摘录他书中第一章中的金句:『一个人如果什么目标都没有,就会浑浑噩噩,感觉生命中缺少能量。能给我们能量的,是对未来的期待。第一件事,我始终为了进步而努力。与其追寻全世界的骏马,不如种植丰美的草原,到时骏马自然会来。第二件事,我始终有阶段性的目标。什么东西能给我能量?答案是对未来的期待。』读到这里的时候,我便</div>
                    </li>
                    <li><a href="/article/1835510025561403392.htm"
                           title="《投行人生》读书笔记" target="_blank">《投行人生》读书笔记</a>
                        <span class="text-muted">小蘑菇的树洞</span>

                        <div>《投行人生》----作者詹姆斯-A-朗德摩根斯坦利副主席40年的职业洞见-很短小精悍的篇幅,比较适合初入职场的新人。第一部分成功的职业生涯需要规划1.情商归为适应能力分享与协作同理心适应能力,更多的是自我意识,你有能力识别自己的情并分辨这些情绪如何影响你的思想和行为。2.对于初入职场的人的建议,细节,截止日期和数据很重要截止日期,一种有效的方法是请老板为你所有的任务进行优先级排序。和老板喝咖啡的好</div>
                    </li>
                    <li><a href="/article/1835506236842405888.htm"
                           title="C#中使用split分割字符串" target="_blank">C#中使用split分割字符串</a>
                        <span class="text-muted">互联网打工人no1</span>
<a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a>
                        <div>1、用字符串分隔:usingSystem.Text.RegularExpressions;stringstr="aaajsbbbjsccc";string[]sArray=Regex.Split(str,"js",RegexOptions.IgnoreCase);foreach(stringiinsArray)Response.Write(i.ToString()+"");输出结果:aaabbbc</div>
                    </li>
                    <li><a href="/article/1835500750684385280.htm"
                           title="拥有断舍离的心态,过精简生活--《断舍离》读书笔记" target="_blank">拥有断舍离的心态,过精简生活--《断舍离》读书笔记</a>
                        <span class="text-muted">爱吃丸子的小樱桃</span>

                        <div>不知不觉间房间里的东西越来越多,虽然摆放整齐,但也时常会觉得空间逼仄,令人心生烦闷。抱着断舍离的态度,我开始阅读《断舍离》这本书,希望从书中能找到一些有效的方法,帮助我实现空间、物品上的断舍离。《断舍离》是日本作家山下英子通过自己的经历、思考和实践总结而成的,整体内涵也从刚开始的私人生活哲学的“断舍离”升华成了“人生实践哲学”,接着又成为每个人都能实行的“改变人生的断舍离”,从“哲学”逐渐升华成“</div>
                    </li>
                    <li><a href="/article/1835498547785592832.htm"
                           title="【华为OD机试真题2023B卷 JAVA&JS】We Are A Team" target="_blank">【华为OD机试真题2023B卷 JAVA&JS】We Are A Team</a>
                        <span class="text-muted">若博豆</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BA/1.htm">华为</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a>
                        <div>华为OD2023(B卷)机试题库全覆盖,刷题指南点这里WeAreATeam时间限制:1秒|内存限制:32768K|语言限制:不限题目描述:总共有n个人在机房,每个人有一个标号(1<=标号<=n),他们分成了多个团队,需要你根据收到的m条消息判定指定的两个人是否在一个团队中,具体的:1、消息构成为:abc,整数a、b分别代</div>
                    </li>
                    <li><a href="/article/1835497074049773568.htm"
                           title="数组去重" target="_blank">数组去重</a>
                        <span class="text-muted">好奇的猫猫猫</span>

                        <div>整理自js中基础数据结构数组去重问题思考?如何去除数组中重复的项例如数组:[1,3,4,3,5]我们在做去重的时候,一开始想到的肯定是,逐个比较,外面一层循环,内层后一个与前一个一比较,如果是久不将当前这一项放进新的数组,挨个比较完之后返回一个新的去过重复的数组不好的实践方式上述方法效率极低,代码量还多,思考?有没有更好的方法这时候不禁一想当然有了!!!hashtable啊,通过对象的hash办法</div>
                    </li>
                    <li><a href="/article/1835494258262503424.htm"
                           title="【JS】执行时长(100分) |思路参考+代码解析(C++)" target="_blank">【JS】执行时长(100分) |思路参考+代码解析(C++)</a>
                        <span class="text-muted">l939035548</span>
<a class="tag" taget="_blank" href="/search/JS/1.htm">JS</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a>
                        <div>题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围</div>
                    </li>
                    <li><a href="/article/1835492740536823808.htm"
                           title="node.js学习" target="_blank">node.js学习</a>
                        <span class="text-muted">小猿L</span>
<a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a>
                        <div>node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行</div>
                    </li>
                    <li><a href="/article/1835485429059645440.htm"
                           title="docker" target="_blank">docker</a>
                        <span class="text-muted">igotyback</span>
<a class="tag" taget="_blank" href="/search/eureka/1.htm">eureka</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a>
                        <div>Docker容器的文件系统是隔离的,但是可以通过挂载卷(Volumes)或绑定挂载(BindMounts)将宿主机的文件系统目录映射到容器内部。要查看Docker容器的映射路径,可以使用以下方法:查看容器配置:使用dockerinspect命令可以查看容器的详细配置信息,包括挂载的卷。例如:bashdockerinspect在输出的JSON格式中,查找"Mounts"部分,这里会列出所有的挂载信息</div>
                    </li>
                    <li><a href="/article/1835480639814594560.htm"
                           title="在Ubuntu中编译含有JSON的文件出现报错" target="_blank">在Ubuntu中编译含有JSON的文件出现报错</a>
                        <span class="text-muted">芝麻糊76</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/kill_bug/1.htm">kill_bug</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a>
                        <div>在ubuntu中进行JSON相关学习的时候,我发现了一些小问题,决定与大家进行分享,减少踩坑时候出现不必要的时间耗费截取部分含有JSON部分的代码进行展示char*str="{\"title\":\"JSONExample\",\"author\":{\"name\":\"JohnDoe\",\"age\":35,\"isVerified\":true},\"tags\":[\"json\",\"</div>
                    </li>
                    <li><a href="/article/1835478496810463232.htm"
                           title="Xinference如何注册自定义模型" target="_blank">Xinference如何注册自定义模型</a>
                        <span class="text-muted">玩人工智能的辣条哥</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/AI/1.htm">AI</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%A8%A1%E5%9E%8B/1.htm">大模型</a><a class="tag" taget="_blank" href="/search/Xinference/1.htm">Xinference</a>
                        <div>环境:Xinference问题描述:Xinference如何注册自定义模型解决方案:1.写个model_config.json,内容如下{"version":1,"context_length":2048,"model_name":"custom-llama-3","model_lang":["en","ch"],"model_ability":["generate","chat"],"model</div>
                    </li>
                    <li><a href="/article/1835471437754888192.htm"
                           title="一文掌握python面向对象魔术方法(二)" target="_blank">一文掌握python面向对象魔术方法(二)</a>
                        <span class="text-muted">程序员neil</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>接上篇:一文掌握python面向对象魔术方法(一)-CSDN博客目录六、迭代和序列化:1、__iter__(self):定义迭代器,使得类可以被for循环迭代。2、__getitem__(self,key):定义索引操作,如obj[key]。3、__setitem__(self,key,value):定义赋值操作,如obj[key]=value。4、__delitem__(self,key):定义</div>
                    </li>
                    <li><a href="/article/1835466664725016576.htm"
                           title="读书笔记|《遇见孩子,遇见更好的自己》5" target="_blank">读书笔记|《遇见孩子,遇见更好的自己》5</a>
                        <span class="text-muted">抹茶社长</span>

                        <div>为人父母意味着放弃自己的过去,不要对以往没有实现的心愿耿耿于怀,只有这样,孩子们才能做回自己。985909803.jpg孩子在与父母保持亲密的同时更需要独立,唯有这样,孩子才会成为孩子,父母才会成其为父母。有耐心的人生往往更幸福,给孩子留点余地。认识到养儿育女是对耐心的考验。为失败做好心理准备,教会孩子控制情绪。了解自己的底线,说到底线,有一点很重要,父母之所以发脾气,真正的原因往往在于他们自己,</div>
                    </li>
                    <li><a href="/article/1835455048277127168.htm"
                           title="Python神器!WEB自动化测试集成工具 DrissionPage" target="_blank">Python神器!WEB自动化测试集成工具 DrissionPage</a>
                        <span class="text-muted">亚丁号</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>一、前言用requests做数据采集面对要登录的网站时,要分析数据包、JS源码,构造复杂的请求,往往还要应付验证码、JS混淆、签名参数等反爬手段,门槛较高。若数据是由JS计算生成的,还须重现计算过程,体验不好,开发效率不高。使用浏览器,可以很大程度上绕过这些坑,但浏览器运行效率不高。因此,这个库设计初衷,是将它们合而为一,能够在不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率</div>
                    </li>
                    <li><a href="/article/1835447985601867776.htm"
                           title="Mongodb Error: queryTxt ETIMEOUT xxxx.wwwdz.mongodb.net" target="_blank">Mongodb Error: queryTxt ETIMEOUT xxxx.wwwdz.mongodb.net</a>
                        <span class="text-muted">佛一脚</span>
<a class="tag" taget="_blank" href="/search/error/1.htm">error</a><a class="tag" taget="_blank" href="/search/react/1.htm">react</a><a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a>
                        <div>背景每天都能遇到奇怪的问题,做个记录,以便有缘人能得到帮助!换了一台电脑开发nextjs程序。需要连接mongodb数据,对数据进行增删改查。上一台电脑好好的程序,新电脑死活连不上mongodb数据库。同一套代码,没任何修改,搞得我怀疑人生了,打开浏览器进入mongodb官网毫无问题,也能进入线上系统查看数据,网络应该是没问题。于是我尝试了一下手机热点,这次代码能正常跑起来,连接数据库了!!!是不</div>
                    </li>
                    <li><a href="/article/1835446687758381056.htm"
                           title="阅读《认知觉醒》读书笔记" target="_blank">阅读《认知觉醒》读书笔记</a>
                        <span class="text-muted">就看看书</span>

                        <div>本周阅读了周岭的《认知觉醒开启自我改变的原动力》,启发较多,故做读书笔记一则,留待学习。全书共八章,讲述了大脑、潜意识、元认知、专注力、学习力、行动力、情绪力及成本最低的成长之道。具体描述了大脑、焦虑、耐心、模糊、感性、元认知、自控力、专注力、情绪专注、学习专注、匹配、深度、关联、体系、打卡、反馈、休息、清晰、傻瓜、行动、心智宽带、单一视角、游戏心态、早起、冥想、阅读、写作、运动等相关知识点。大脑</div>
                    </li>
                    <li><a href="/article/1835443569528238080.htm"
                           title="Vue( ElementUI入门、vue-cli安装)" target="_blank">Vue( ElementUI入门、vue-cli安装)</a>
                        <span class="text-muted">m0_l5z</span>
<a class="tag" taget="_blank" href="/search/elementui/1.htm">elementui</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a>
                        <div>一.ElementUI入门目录:1.ElementUI入门1.1ElementUI简介1.2Vue+ElementUI安装1.3开发示例2.搭建nodejs环境2.1nodejs介绍2.2npm是什么2.3nodejs环境搭建2.3.1下载2.3.2解压2.3.3配置环境变量2.3.4配置npm全局模块路径和cache默认安装位置2.3.5修改npm镜像提高下载速度2.3.6验证安装结果3.运行n</div>
                    </li>
                    <li><a href="/article/1835437775344726016.htm"
                           title="博客网站制作教程" target="_blank">博客网站制作教程</a>
                        <span class="text-muted">2401_85194651</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a>
                        <div>首先就是技术框架:后端:Java+SpringBoot数据库:MySQL前端:Vue.js数据库连接:JPA(JavaPersistenceAPI)1.项目结构blog-app/├──backend/│├──src/main/java/com/example/blogapp/││├──BlogApplication.java││├──config/│││└──DatabaseConfig.java</div>
                    </li>
                    <li><a href="/article/1835435506645692416.htm"
                           title="00. 这里整理了最全的爬虫框架(Java + Python)" target="_blank">00. 这里整理了最全的爬虫框架(Java + Python)</a>
                        <span class="text-muted">有一只柴犬</span>
<a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB%E7%B3%BB%E5%88%97/1.htm">爬虫系列</a><a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/1.htm">爬虫</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>目录1、前言2、什么是网络爬虫3、常见的爬虫框架3.1、java框架3.1.1、WebMagic3.1.2、Jsoup3.1.3、HttpClient3.1.4、Crawler4j3.1.5、HtmlUnit3.1.6、Selenium3.2、Python框架3.2.1、Scrapy3.2.2、BeautifulSoup+Requests3.2.3、Selenium3.2.4、PyQuery3.2</div>
                    </li>
                    <li><a href="/article/1835431726982197248.htm"
                           title="vue 创建项目报错:command failed: npm install --loglevel error" target="_blank">vue 创建项目报错:command failed: npm install --loglevel error</a>
                        <span class="text-muted">那鱼、会飞</span>
<a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/vue-cli3/1.htm">vue-cli3</a>
                        <div>这个问题其实很好解决,只是很多种情况,逐一排除即可。稳下心来~vuecli3创建项目我的node版本是node14.15.0,(永远不要尝试最新版本)node各种版本下载地址:以往的版本|Node.js(nodejs.org)vue/cli@3.12.1npminstall-g@vue/cli@3.12.1(注意vue/cli2和vue/cli3的下载命名有所改变,2是-形式,3是/形式)其实报错</div>
                    </li>
                    <li><a href="/article/1835430719363575808.htm"
                           title="更改npm镜像源为淘宝镜像" target="_blank">更改npm镜像源为淘宝镜像</a>
                        <span class="text-muted">骆小骆</span>
<a class="tag" taget="_blank" href="/search/%E5%9F%BA%E4%BA%8Enode.js/1.htm">基于node.js</a>
                        <div>npm常用指令后缀*最近复习了一下node.js整理了一下跟node.js相关的指令后缀*--save、-S参数意思是把模块的版本信息保存到dependencies(生产环境依赖)中,即你的package.json文件的dependencies字段中;–--save-dev、-D参数意思是把模块版本信息保存到devDependencies(开发环境依赖)中,即你的package.json文件的de</div>
                    </li>
                    <li><a href="/article/1835430340806668288.htm"
                           title="COCO 格式的数据集转化为 YOLO 格式的数据集" target="_blank">COCO 格式的数据集转化为 YOLO 格式的数据集</a>
                        <span class="text-muted">QYQY77</span>
<a class="tag" taget="_blank" href="/search/YOLO/1.htm">YOLO</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>"""--json_path输入的json文件路径--save_path保存的文件夹名字,默认为当前目录下的labels。"""importosimportjsonfromtqdmimporttqdmimportargparseparser=argparse.ArgumentParser()parser.add_argument('--json_path',default='./instances</div>
                    </li>
                    <li><a href="/article/1835415332345442304.htm"
                           title="NPM私库搭建-verdaccio(Linux)" target="_blank">NPM私库搭建-verdaccio(Linux)</a>
                        <span class="text-muted">Beam007</span>
<a class="tag" taget="_blank" href="/search/npm/1.htm">npm</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>1、安装nodelinux服务器安装nodea)、官网下载所需的node版本https://nodejs.org/dist/v14.21.0/b)、解压安装包若下载的是xxx.tar.xz文件,解压命令为tar-xvfxxx.tar.xzc)、修改环境变量修改:/etc/profile文件#SETPATHFORNODEJSexportNODE_HOME=NODEJS解压安装的路径exportPAT</div>
                    </li>
                    <li><a href="/article/1835414702142877696.htm"
                           title="Python编程 - 函数进阶" target="_blank">Python编程 - 函数进阶</a>
                        <span class="text-muted">易辰君</span>
<a class="tag" taget="_blank" href="/search/Python%E6%A0%B8%E5%BF%83%E7%BC%96%E7%A8%8B/1.htm">Python核心编程</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>目录前言一、函数参数的高级用法(一)缺省参数(二)命名参数(三)不定长参数二、拆包(一)函数返回值拆包(二)通过星号拆包(三)总结三、匿名函数(一)函数定义(二)使用匿名函数四、递归函数(一)简介(二)基本结构(三)简单示例(四)优缺点总结前言上篇文章主要了解了函数基础,如何定义函数,函数种类以及局部变量和全局变量的差异等,接下来就讲解python函数较为进阶的知识点,若有任何想法欢迎一起沟通讨论</div>
                    </li>
                    <li><a href="/article/1835409406653722624.htm"
                           title="信息系统安全相关概念(下)" target="_blank">信息系统安全相关概念(下)</a>
                        <span class="text-muted">YuanDaima2048</span>
<a class="tag" taget="_blank" href="/search/%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5/1.htm">基础概念</a><a class="tag" taget="_blank" href="/search/%E8%AF%BE%E7%A8%8B%E7%AC%94%E8%AE%B0/1.htm">课程笔记</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a>
                        <div>文章总览:YuanDaiMa2048博客文章总览上篇指路:信息系统安全相关概念(上)信息系统安全相关概念[下]信息系统风险评估安全风险评估信息系统等级保护网络安全法等级保护等级保护工作流程环境安全信息系统风险评估安全风险评估对信息系统整体安全态势的感知和对重大安全事件的预警,实现“事前能预防,事中能控制,事后能处理”。安全风险组成的四要素:信息系统资产(Asset)信息系统脆弱性(Vulnerab</div>
                    </li>
                    <li><a href="/article/1835398064727224320.htm"
                           title="前端代码上传文件" target="_blank">前端代码上传文件</a>
                        <span class="text-muted">余生逆风飞翔</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>点击上传文件import{ElNotification}from'element-plus'import{API_CONFIG}from'../config/index.js'import{UploadFilled}from'@element-plus/icons-vue'import{reactive}from'vue'import{BASE_URL}from'../config/index'i</div>
                    </li>
                    <li><a href="/article/1835397938482868224.htm"
                           title="golang获取用户输入的几种方式" target="_blank">golang获取用户输入的几种方式</a>
                        <span class="text-muted">余生逆风飞翔</span>
<a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a>
                        <div>一、定义结构体typeUserInfostruct{Namestring`json:"name"`Ageint`json:"age"`Addstring`json:"add"`}typeReturnDatastruct{Messagestring`json:"message"`Statusstring`json:"status"`DataUserInfo`json:"data"`}二、get请求的</div>
                    </li>
                    <li><a href="/article/1835393400380157952.htm"
                           title="VUE3 + xterm + nestjs实现web远程终端 或 连接开启SSH登录的路由器和交换机。" target="_blank">VUE3 + xterm + nestjs实现web远程终端 或 连接开启SSH登录的路由器和交换机。</a>
                        <span class="text-muted">焚木灵</span>
<a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/vue/1.htm">vue</a>
                        <div>可远程连接系统终端或开启SSH登录的路由器和交换机。相关资料:xtermjs/xterm.js:Aterminalfortheweb(github.com)后端实现(NestJS):1、安装依赖:npminstallnode-ssh@nestjs/websockets@nestjs/platform-socket.io2、我们将创建一个名为RemoteControlModule的NestJS模块,</div>
                    </li>
                    <li><a href="/article/1835379153730367488.htm"
                           title="spring mvc @RequestBody String类型参数" target="_blank">spring mvc @RequestBody String类型参数</a>
                        <span class="text-muted">zoyation</span>
<a class="tag" taget="_blank" href="/search/spring-mvc/1.htm">spring-mvc</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/mvc/1.htm">mvc</a>
                        <div>通过如下配置:text/html;charset=UTF-8application/json;charset=UTF-8在springmvc的Controller层使用@RequestBody接收Content-Type为application/json的数据时,默认支持Map方式和对象方式参数@RequestMapping(value="/{code}/saveUser",method=Requ</div>
                    </li>
                                <li><a href="/article/17.htm"
                                       title="分享100个最新免费的高匿HTTP代理IP" target="_blank">分享100个最新免费的高匿HTTP代理IP</a>
                                    <span class="text-muted">mcj8089</span>
<a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%90%86IP/1.htm">代理IP</a><a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">代理服务器</a><a class="tag" taget="_blank" href="/search/%E5%8C%BF%E5%90%8D%E4%BB%A3%E7%90%86/1.htm">匿名代理</a><a class="tag" taget="_blank" href="/search/%E5%85%8D%E8%B4%B9%E4%BB%A3%E7%90%86IP/1.htm">免费代理IP</a><a class="tag" taget="_blank" href="/search/%E6%9C%80%E6%96%B0%E4%BB%A3%E7%90%86IP/1.htm">最新代理IP</a>
                                    <div>  
推荐两个代理IP网站: 
  
1. 全网代理IP:http://proxy.goubanjia.com/ 
  
2. 敲代码免费IP:http://ip.qiaodm.com/ 
  
  
120.198.243.130:80,中国/广东省
58.251.78.71:8088,中国/广东省
183.207.228.22:83,中国/</div>
                                </li>
                                <li><a href="/article/144.htm"
                                       title="mysql高级特性之数据分区" target="_blank">mysql高级特性之数据分区</a>
                                    <span class="text-muted">annan211</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%8C%BA/1.htm">分区</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>


mysql高级特性
  1 以存储引擎的角度分析,分区表和物理表没有区别。是按照一定的规则将数据分别存储的逻辑设计。器底层是由多个物理字表组成。
  
  2 分区的原理
     分区表由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们可以直接访问各个分区。存储引擎管理分区的各个底层
	 表和管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只是</div>
                                </li>
                                <li><a href="/article/271.htm"
                                       title="JS采用正则表达式简单获取URL地址栏参数" target="_blank">JS采用正则表达式简单获取URL地址栏参数</a>
                                    <span class="text-muted">chiangfai</span>
<a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/%E5%9C%B0%E5%9D%80%E6%A0%8F%E5%8F%82%E6%95%B0%E8%8E%B7%E5%8F%96/1.htm">地址栏参数获取</a>
                                    <div>GetUrlParam:function GetUrlParam(param){
		var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)");
		var r = window.location.search.substr(1).match(reg);
		if(r!=null</div>
                                </li>
                                <li><a href="/article/398.htm"
                                       title="怎样将数据表拷贝到powerdesigner (本地数据库表)" target="_blank">怎样将数据表拷贝到powerdesigner (本地数据库表)</a>
                                    <span class="text-muted">Array_06</span>
<a class="tag" taget="_blank" href="/search/powerDesigner/1.htm">powerDesigner</a>
                                    <div>================================================== 
 
1、打开PowerDesigner12,在菜单中按照如下方式进行操作 
file->Reverse Engineer->DataBase 
点击后,弹出 New Physical Data Model 的对话框 
2、在General选项卡中 
Model name:模板名字,自</div>
                                </li>
                                <li><a href="/article/525.htm"
                                       title="logbackのhelloworld" target="_blank">logbackのhelloworld</a>
                                    <span class="text-muted">飞翔的马甲</span>
<a class="tag" taget="_blank" href="/search/%E6%97%A5%E5%BF%97/1.htm">日志</a><a class="tag" taget="_blank" href="/search/logback/1.htm">logback</a>
                                    <div>一、概述 
 
1.日志是啥? 
当我是个逗比的时候我是这么理解的:log.debug()代替了system.out.print(); 
当我项目工作时,以为是一堆得.log文件。 
这两天项目发布新版本,比较轻松,决定好好地研究下日志以及logback。 
传送门1:日志的作用与方法: 
http://www.infoq.com/cn/articles/why-and-how-log 
上面的作</div>
                                </li>
                                <li><a href="/article/652.htm"
                                       title="新浪微博爬虫模拟登陆" target="_blank">新浪微博爬虫模拟登陆</a>
                                    <span class="text-muted">随意而生</span>
<a class="tag" taget="_blank" href="/search/%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A/1.htm">新浪微博</a>
                                    <div>转载自:http://hi.baidu.com/erliang20088/item/251db4b040b8ce58ba0e1235 
  
  
近来由于毕设需要,重新修改了新浪微博爬虫废了不少劲,希望下边的总结能够帮助后来的同学们。 
     现行版的模拟登陆与以前相比,最大的改动在于cookie获取时候的模拟url的请求</div>
                                </li>
                                <li><a href="/article/779.htm"
                                       title="synchronized" target="_blank">synchronized</a>
                                    <span class="text-muted">香水浓</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a>
                                    <div>    Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然</div>
                                </li>
                                <li><a href="/article/906.htm"
                                       title="maven 简单实用教程" target="_blank">maven 简单实用教程</a>
                                    <span class="text-muted">AdyZhang</span>
<a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a>
                                    <div>1. Maven介绍  1.1. 简介 java编写的用于构建系统的自动化工具。目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。 1.2. Maven资源 见官方网站;The 5 minute test,官方简易入门文档;Getting Started Tutorial,官方入门文档;Build Coo</div>
                                </li>
                                <li><a href="/article/1033.htm"
                                       title="Android 通过 intent传值获得null" target="_blank">Android 通过 intent传值获得null</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>我在通过intent 获得传递兑现过的时候报错,空指针,我是getMap方法进行传值,代码如下        1   2   3   4   5   6   7   8   9      
public 
void 
getMap(View view){       
         
Intent i =</div>
                                </li>
                                <li><a href="/article/1160.htm"
                                       title="apache 做代理 报如下错误:The proxy server received an invalid response from an upstream" target="_blank">apache 做代理 报如下错误:The proxy server received an invalid response from an upstream</a>
                                    <span class="text-muted">baalwolf</span>
<a class="tag" taget="_blank" href="/search/response/1.htm">response</a>
                                    <div>网站配置是apache+tomcat,tomcat没有报错,apache报错是: 
The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr</div>
                                </li>
                                <li><a href="/article/1287.htm"
                                       title="Tomcat6 内存和线程配置" target="_blank">Tomcat6 内存和线程配置</a>
                                    <span class="text-muted">BigBird2012</span>
<a class="tag" taget="_blank" href="/search/tomcat6/1.htm">tomcat6</a>
                                    <div>1、修改启动时内存参数、并指定JVM时区 (在windows server 2008 下时间少了8个小时) 
在Tomcat上运行j2ee项目代码时,经常会出现内存溢出的情况,解决办法是在系统参数中增加系统参数:  
window下, 在catalina.bat最前面 
  set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m -Xms5</div>
                                </li>
                                <li><a href="/article/1414.htm"
                                       title="Karam与TDD" target="_blank">Karam与TDD</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/Karam/1.htm">Karam</a><a class="tag" taget="_blank" href="/search/TDD/1.htm">TDD</a>
                                    <div>一.TDD 
        测试驱动开发(Test-Driven Development,TDD)是一种敏捷(AGILE)开发方法论,它把开发流程倒转了过来,在进行代码实现之前,首先保证编写测试用例,从而用测试来驱动开发(而不是把测试作为一项验证工具来使用)。 
        TDD的原则很简单: 
a.只有当某个</div>
                                </li>
                                <li><a href="/article/1541.htm"
                                       title="[Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States" target="_blank">[Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a>
                                    <div>    public enum States {
        CONNECTING, //Zookeeper服务器不可用,客户端处于尝试链接状态
        ASSOCIATING, //???
        CONNECTED, //链接建立,可以与Zookeeper服务器正常通信
        CONNECTEDREADONLY, //处于只读状态的链接状态,只读模式可以在</div>
                                </li>
                                <li><a href="/article/1668.htm"
                                       title="【Scala十四】Scala核心八:闭包" target="_blank">【Scala十四】Scala核心八:闭包</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a>
                                    <div>Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x</div>
                                </li>
                                <li><a href="/article/1795.htm"
                                       title="android发送json并解析返回json" target="_blank">android发送json并解析返回json</a>
                                    <span class="text-muted">ronin47</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>package com.http.test; 
 
 
import org.apache.http.HttpResponse; 
import org.apache.http.HttpStatus; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import </div>
                                </li>
                                <li><a href="/article/1922.htm"
                                       title="一份IT实习生的总结" target="_blank">一份IT实习生的总结</a>
                                    <span class="text-muted">brotherlamp</span>
<a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/php%E8%B5%84%E6%96%99/1.htm">php资料</a><a class="tag" taget="_blank" href="/search/php%E6%95%99%E7%A8%8B/1.htm">php教程</a><a class="tag" taget="_blank" href="/search/php%E5%9F%B9%E8%AE%AD/1.htm">php培训</a><a class="tag" taget="_blank" href="/search/php%E8%A7%86%E9%A2%91/1.htm">php视频</a>
                                    <div>今天突然发现在不知不觉中自己已经实习了 3 个月了,现在可能不算是真正意义上的实习吧,因为现在自己才大三,在这边撸代码的同时还要考虑到学校的功课跟期末考试。让我震惊的是,我完全想不到在这 3 个月里我到底学到了什么,这是一件多么悲催的事情啊。同时我对我应该 get 到什么新技能也很迷茫。所以今晚还是总结下把,让自己在接下来的实习生活有更加明确的方向。最后感谢工作室给我们几个人这个机会让我们提前出来</div>
                                </li>
                                <li><a href="/article/2049.htm"
                                       title="据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码" target="_blank">据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>
public class ScalesBalance {

	/**
	 * 题目:
	 * 给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 (假设N无限大,但一种重量的砝码只有一个)
	 * 将重物放到天平左侧,问在两边如何添加砝码使两边平衡
	 * 
	 * 分析:
	 * 三进制
	 * 我们约定括号表示里面的数是三进制,例如 47=(1202</div>
                                </li>
                                <li><a href="/article/2176.htm"
                                       title="dom4j最常用最简单的方法" target="_blank">dom4j最常用最简单的方法</a>
                                    <span class="text-muted">chiangfai</span>
<a class="tag" taget="_blank" href="/search/dom4j/1.htm">dom4j</a>
                                    <div>要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip 
解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要</div>
                                </li>
                                <li><a href="/article/2303.htm"
                                       title="简单HBase笔记" target="_blank">简单HBase笔记</a>
                                    <span class="text-muted">chenchao051</span>
<a class="tag" taget="_blank" href="/search/hbase/1.htm">hbase</a>
                                    <div> 一、Client-side write buffer 客户端缓存请求   描述:可以缓存客户端的请求,以此来减少RPC的次数,但是缓存只是被存在一个ArrayList中,所以多线程访问时不安全的。   可以使用getWriteBuffer()方法来取得客户端缓存中的数据。 默认关闭。      二、Scan的Caching   描述: next( )方法请求一行就要使用一次RPC,即使</div>
                                </li>
                                <li><a href="/article/2430.htm"
                                       title="mysqldump导出时出现when doing LOCK TABLES" target="_blank">mysqldump导出时出现when doing LOCK TABLES</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/mysqdump/1.htm">mysqdump</a><a class="tag" taget="_blank" href="/search/%E5%AF%BC%E6%95%B0%E6%8D%AE/1.htm">导数据</a>
                                    <div>  执行 mysqldump -uxxx -pxxx -hxxx -Pxxxx database tablename > tablename.sql  
导出表时,会报 
 
mysqldump: Got error: 1044: Access denied for user 'xxx'@'xxx' to database 'xxx' when doing LOCK TABLES 
 
解决</div>
                                </li>
                                <li><a href="/article/2557.htm"
                                       title="CSS渲染原理" target="_blank">CSS渲染原理</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a>
                                    <div>   从事Web前端开发的人都与CSS打交道很多,有的人也许不知道css是怎么去工作的,写出来的css浏览器是怎么样去解析的呢?当这个成为我们提高css水平的一个瓶颈时,是否应该多了解一下呢?   
  
       一、浏览器的发展与CSS      
  
   </div>
                                </li>
                                <li><a href="/article/2684.htm"
                                       title="《阿甘正传》台词" target="_blank">《阿甘正传》台词</a>
                                    <span class="text-muted">dcj3sjt126com</span>

                                    <div>Part Ⅰ: 
《阿甘正传》Forrest Gump经典中英文对白 
Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol</div>
                                </li>
                                <li><a href="/article/2811.htm"
                                       title="Java处理JSON" target="_blank">Java处理JSON</a>
                                    <span class="text-muted">dyy_gusi</span>
<a class="tag" taget="_blank" href="/search/json/1.htm">json</a>
                                    <div>Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。 
在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下: 
1、读取json然后处理 
class ReadJSON
{
    public static void main(String[] args)
    </div>
                                </li>
                                <li><a href="/article/2938.htm"
                                       title="win7下nginx和php的配置" target="_blank">win7下nginx和php的配置</a>
                                    <span class="text-muted">geeksun</span>
<a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a>
                                    <div>1.  安装包准备 
nginx :  从nginx.org下载nginx-1.8.0.zip 
php: 从php.net下载php-5.6.10-Win32-VC11-x64.zip, php是免安装文件。 
RunHiddenConsole: 用于隐藏命令行窗口 
  
2. 配置 
# java用8080端口做应用服务器,nginx反向代理到这个端口即可 
p</div>
                                </li>
                                <li><a href="/article/3065.htm"
                                       title="基于2.8版本redis配置文件中文解释" target="_blank">基于2.8版本redis配置文件中文解释</a>
                                    <span class="text-muted">hongtoushizi</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>转载自: http://wangwei007.blog.51cto.com/68019/1548167 
       在Redis中直接启动redis-server服务时, 采用的是默认的配置文件。采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务。下面是Redis2.8.9的配置文</div>
                                </li>
                                <li><a href="/article/3192.htm"
                                       title="第五章 常用Lua开发库3-模板渲染" target="_blank">第五章 常用Lua开发库3-模板渲染</a>
                                    <span class="text-muted">jinnianshilongnian</span>
<a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/lua/1.htm">lua</a>
                                    <div>动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。 
  
如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r</div>
                                </li>
                                <li><a href="/article/3319.htm"
                                       title="JZSearch大数据搜索引擎" target="_blank">JZSearch大数据搜索引擎</a>
                                    <span class="text-muted">颠覆者</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div>系统简介: 
 
 大数据的特点有四个层面:第一,数据体量巨大。从TB级别,跃升到PB级别;第二,数据类型繁多。网络日志、视频、图片、地理位置信息等等。第三,价值密度低。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。最后这一点也是和传统的数据挖掘技术有着本质的不同。业界将其归纳为4个“V”——Volume,Variety,Value,Velocity。大数据搜索引</div>
                                </li>
                                <li><a href="/article/3446.htm"
                                       title="10招让你成为杰出的Java程序员" target="_blank">10招让你成为杰出的Java程序员</a>
                                    <span class="text-muted">pda158</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a><a class="tag" taget="_blank" href="/search/%E6%A1%86%E6%9E%B6/1.htm">框架</a>
                                    <div>如果你是一个热衷于技术的  
Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出。      
1. 拥有扎实的基础和深刻理解 OO 原则     对于 Java 程序员,深刻理解 Object Oriented Programming(面向对象编程)这一概念是必须的。没有 OOPS 的坚实基础,就领会不了像 Java 这些面向对象编程语言</div>
                                </li>
                                <li><a href="/article/3573.htm"
                                       title="tomcat之oracle连接池配置" target="_blank">tomcat之oracle连接池配置</a>
                                    <span class="text-muted">小网客</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a>
                                    <div>tomcat版本7.0 
配置oracle连接池方式: 
修改tomcat的server.xml配置文件: 
 <GlobalNamingResources>
 
			  <Resource name="utermdatasource" auth="Container"  
 type="javax.sql.DataSou</div>
                                </li>
                                <li><a href="/article/3700.htm"
                                       title="Oracle 分页算法汇总" target="_blank">Oracle 分页算法汇总</a>
                                    <span class="text-muted">vipbooks</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a>
                                    <div>    这是我找到的一些关于Oracle分页的算法,大家那里还有没有其他好的算法没?我们大家一起分享一下! 
 
 

-- Oracle 分页算法一
select * from (
       select page.*,rownum rn from (select * from help) page 
       -- 20 = (currentPag</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>