前面的话

  随着JS应用复杂度的不断增加,开发者在程序中使用对象的数量也在持续增长,因此对象使用效率的提升就变得至关重要。ES6通过多种方式来加强对象的使用,通过简单的语法扩展,提供更多操作对象及与对象交互的方法。本章将详细介绍ES6对象扩展

对象类别

  在浏览器这样的执行环境中,对象没有统一的标准,在标准中又使用不同的术语描述对象,ES6规范清晰定义了每一个类别的对象,对象的类别如下

  1、普通(Ordinary)对象

  具有JS对象所有的默认内部行为

  2、特异(Exotic)对象

  具有某些与默认行为不符的内部行为

  3、标准(Standard)对象

  ES6规范中定义的对象,例如,Array、Date等。标准对象既可以是普通对象,也可以是特异对象

  4、内建对象

  脚本开始执行时存在于JS执行环境中的对象,所有标准对象都是内建对象

对象简写

【属性初始值简写】

  在ES5中,对象字面量只是简单的键值对集合,这意味着初始化属性值时会有一些重复

function createPerson(name, age) {
return {
name: name,
age: age
};
}

  这段代码中的createPerson()函数创建了一个对象,其属性名称与函数的参数相同,在返回的结果中,name和age分别重复了两遍,只是其中一个是对象属性的名称,另外一个是为属性赋值的变量

  在ES6中,通过使用属性初始化的简写语法,可以消除这种属性名称与局部变量之间的重复书写。当一个对象的属性与本地变量同名时,不必再写冒号和值,简单地只写属性名即可

function createPerson(name, age) {
return {
name,
age
};
}

  当对象字面量里只有一个属性的名称时,JS引擎会在可访问作用域中查找其同名变量;如果找到,则该变量的值被赋给对象字面量里的同名属性。在本示例中,对象字面量属性name被赋予了局部变量name的值

  在JS中,为对象字面量的属性赋同名局部变量的值是一种常见的做法,这种简写方法有助于消除命名错误

【对象方法简写】

  在ES5中,如果为对象添加方法,必须通过指定名称并完整定义函数来实现

var person = {
name: "Nicholas",
sayName: function() {
console.log(this.name);
}
};

  而在ES6中,语法更简洁,消除了冒号和function关键字

var person = {
name: "Nicholas",
sayName() {
console.log(this.name);
}
};

  在这个示例中,通过对象方法简写语法,在person对象中创建一个sayName()方法,该属性被赋值为一个匿名函数表达式,它拥有在ES5中定义的对象方法所具有的全部特性

  二者唯一的区别是,简写方法可以使用super关键字,而普通方法不可以

  [注意]通过对象方法简写语法创建的方法有一个name属性,其值为小括号前的名称

可计算属性名

  在ES5版本中,如果想要通过计算得到属性名,就需要用方括号代替点记法

var person = {},
lastName = "last name";
person["first name"] = "huochai";
person[lastName] = "match";
console.log(person["first name"]); // "huochai"
console.log(person[lastName]); // "match"

  变量lastName被赋值为字符串"last name",引用的两个属性名称中都含有空格,因而不可使用点记法引用这些属性,却可以使用方括号,因为它支持通过任何字符串值作为名称访问属性的值。此外,在对象字面量中,可以直接使用字符串字面量作为属性名称

var person = {
"first name": "huochai"
};
console.log(person["first name"]); // "huochai"

  这种模式适用于属性名提前已知或可被字符串字面量表示的情况。然而,如果属性名称"first name"被包含在一个变量中,或者需要通过计算才能得到该变量的值,那么在ES5中是无法为一个对象字面量定义该属性的

  在ES6中,可在对象字面量中使用可计算属性名称,其语法与引用对象实例的可计算属性名称相同,也是使用方括号

var lastName = "last name";
var person = {
"first name": "huochai",
[lastName]: "match"
};
console.log(person["first name"]); // "huochai"
console.log(person[lastName]); // "match"

  在对象字面量中使用方括号表示的该属性名称是可计算的,它的内容将被名称求值并被最终转化为一个字符串,因而同样可以使用表达式作为属性的可计算名称

var suffix = " name";
var person = {
["first" + suffix]: "huochai",
["last" + suffix]: "match"
};
console.log(person["first name"]); // "huochai"
console.log(person["last name"]); // "match"

  这些属性被求值后为字符串"first name"和"last name",然后它们可用于属性引用。任何可用于对象实例括号记法的属性名,也可以作为字面量中的计算属性名

判断相等

【Object.is()】

  在JS中比较两个值时,可能习惯于使用相等运算符(==)或全等运算符(===),使用后者可以避免触发强制类型转换的行为。但是,即使使用全等运算符也不完全准确

console.log(+0 === -0);//true
console.log(NaN === NaN);//false

  ES6引入了Object.is()方法来弥补全等运算符的不准确运算。这个方法接受两个参数,如果这两个参数类型相等且具有相同的值,则返回true,否则返回false

console.log(+0 == -0); // true
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
console.log(5 == 5); // true
console.log(5 == "5"); // true
console.log(5 === 5); // true
console.log(5 === "5"); // false
console.log(Object.is(5, 5)); // true
console.log(Object.is(5, "5")); // false

  对于Object.is()方法来说,其运行结果在大部分情况中与"==="运算符相同,唯一的区别在于+0和-0被识别为不相等并且NaN与NaN等价。但是大可不必抛弃等号运算符,是否选择用Object.is()方法而不是==或===取决于那些特殊情况如何影响代码

对象合并

【Object.assign()】

  混合(Mixin)是JS实现对象组合最流行的一种模式。在一个mixin方法中,一个对象接收来自另一个对象的属性和方法,许多JS库中都有类似的minix方法

function mixin(receiver, supplier) {
Object.keys(supplier).forEach(function(key) {
receiver[key] = supplier[key];
});
return receiver;
}

  mixin()函数遍历supplier的自有属性并复制到receiver中(此处的复制行为是浅复制,当属性值为对象时只复制对象的引用)。这样一来,receiver不通过继承就可以获得新属性

function EventTarget() { /*...*/ }
EventTarget.prototype = {
constructor: EventTarget,
emit: function() { /*...*/ },
on: function() { /*...*/ }
};
var myObject = {};
mixin(myObject, EventTarget.prototype);
myObject.emit("somethingChanged");

  在这段代码中,myObject继承EventTarget.prototype对象的所有行为,从而使myObject可以分别通过emit()方法发布事件或通过on()方法订阅事件

  这种混合模式非常流行,因而ES6添加了object.assign()方法来实现相同的功能,这个方法接受一个接收对象和任意数量的源对象,最终返回接收对象

function EventTarget() { /*...*/ }
EventTarget.prototype = {
constructor: EventTarget,
emit: function() { /*...*/ },
on: function() { /*...*/ }
}
var myObject = {}
Object.assign(myObject, EventTarget.prototype);
myObject.emit("somethingChanged");

【对象合并】

  Object.assign()方法不叫对象复制,或对象拷贝,而叫对象合并,是因为源对象本身的属性和方法仍然存在

var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 }; Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

  Object.assign()方法可以接受任意数量的源对象,并按指定的顺序将属性复制到接收对象中。如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性

var target = { a: 1, b: 1 };
var source1 = { b: 2, c: 2 };
var source2 = { c: 3 }; Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

【浅拷贝】

  在对象合并的过程中,Object.assign()拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false

Object.assign({b: 'c'},
Object.defineProperty({}, 'invisible', {
enumerable: false,
value: 'hello'
})
)
// { b: 'c' }

  Object.assign()方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用

var obj1 = {a: {b: 1}};
var obj2 = Object.assign({}, obj1); obj1.a.b = 2;
obj2.a.b //

【展开运算符】

  在ES7中,支持对象展开运算符的写法,来替代Object.assign()

Object.assign({}, state, {visibilityFilter: action.filter})
//等同于
{ ...state, visibilityFilter: action.filter }

  [注意]在某些情况下,展开运行符的写法不生效

  在nodejs中使用mongoose数据库筛选数据时要使用Object.assign()。如果使用...t,会输出一些无用的值

"$__": {
"strictMode": true,
"selected": {
"_id": ,
"content":
},
"getters": {},
"wasPopulated": false,
"activePaths": {
"paths": {
"title": "init",
"categories": "default",
"comments": "default",
"likes": "default",
"collections": "default",
"createdAt": "init",
"updatedAt": "init",
"__v": "init"
},
...

属性名重复

  ES5严格模式中加入了对象字面量重复属性的校验,当同时存在多个同名属性时会抛出错误

"use strict";
var person = {
name: "huochai",
name: "match" // 在 ES5 严格模式中是语法错误
};

  当运行在ES5严格模式下时,第二个name属性会触发二个语法错误

  但在ES6中,重复属性检查被移除了,无论是在严格模式还是非严格模式下,代码不再检查重复属性,对于每一组重复属性,都会选取最后一个取值

"use strict";
var person = {
name: "huochai",
name: "match"
};
console.log(person.name); // "match"

  在这个示例中,属性person.name取最后一次赋值"match"

枚举顺序

  ES5中未定义对象属性的枚举顺序,由JS引擎厂商自行决定。然而,ES6严格规定了对象的自有属性被枚举时的返回顺序,这会影响到Object.getOwnPropertyNames()方法及Reflect.ownKeys返回属性的方式,Object.assign()方法处理属性的顺序也将随之改变

  自有属性枚举顺序的基本规则是

  1、所有数字键按升序排序

  2、所有字符串键按照它们被加入对象的顺序排序

  3、所有symbol键按照它们被加入对象的顺序排序

var obj = {
a: 1,
0: 1,
c: 1,
2: 1,
b: 1,
1: 1
};
obj.d = 1;
console.log(Object.getOwnPropertyNames(obj).join("")); // "012acbd"

  Object.getOwnPropertyNames()方法按照0、1、2、a、c、b、d的顺序依次返回对象obj中定义的属性。对于数值键,尽管在对象字面量中的顺序是随意的,但在枚举时会被重新组合和排序。字符串键紧随数值键,并按照在对象obj中定义的顺序依次返回,所以随后动态加入的字符串键最后输出

  [注意]对于for-in循环,由于并非所有厂商都遵循相同的实现方式,因此仍未指定一个明确的枚举顺序而Object.keys()方法和JSON.stringify()方法都指明与for-in使用相同的枚举顺序,因此它们的枚举顺序目前也不明晰

  对于JS,枚举顺序的改变其实微不足道,但是有很多程序都需要明确指定枚举顺序才能正确运行。ES6中通过明确定义枚举顺序,确保用到枚举的代码无论处于何处都可以正确地执行

对象原型

  原型是JS继承的基础,在早期版本中,JS严重限制了原型的使用。随着语言逐渐成熟,开发者们也更加熟悉原型的运行方式,他们希望获得更多对于原型的控制力,并以更简单的方式来操作原型。于是,ES6针对原型进行了改进

【__proto__】

  __proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括IE11)都部署了这个属性

// es6的写法
var obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj; // es5的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };

  标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替

【Object.getPrototypeOf()】

  该方法与Object.setPrototypeOf()方法配套,用于读取一个对象的原型对象

Object.getPrototypeOf(obj);

【Object.setPrototypeOf()】

  ES6添加了Object.setPrototypeOf()方法,与__proto__作用相同,通过这个方法可以改变任意指定对象的原型,它接受两个参数:被改变原型的对象及替代第一个参数原型的对象,它是ES6正式推荐的设置原型对象的方法

// 格式
Object.setPrototypeOf(object, prototype) // 用法
var o = Object.setPrototypeOf({}, null);

  例子如下

let person = {
getGreeting() {
return "Hello";
}
};
let dog = {
getGreeting() {
return "Woof";
}
};
// 原型为 person
let friend = Object.create(person);
console.log(friend.getGreeting()); // "Hello"
console.log(Object.getPrototypeOf(friend) === person); // true
// 将原型设置为 dog
Object.setPrototypeOf(friend, dog);
console.log(friend.getGreeting()); // "Woof"
console.log(Object.getPrototypeOf(friend) === dog); // true

  这段代码中定义了两个基对象:person和dog。二者都有getGreeting()方法,且都返回一个字符串。friend对象先继承person对象,调用getGreeting()方法输出"Hello";当原型被变更为dog对象时,原先与person对象的关联被解除,调用person.getGreeting()方法时输出的内容就变为了"Woof"

  对象原型的真实值被储存在内部专用属性[[protơtype]]中,调用Object.getPrototypeOf()方法返回储存在其中的值,调用Object.setPrototypeOf()方法改变其中的值。然而,这不是操作[[prototype]]值的唯一方法

【简化原型访问的Super引用】

  ES6引入了Super引用,使用它可以更便捷地访问对象原型

  如果想重写对象实例的方法,又需要调用与它同名的原型方法,则在ES5中可以这样实现

let person = {
getGreeting() {
return "Hello";
}
};
let dog = {
getGreeting() {
return "Woof";
}
};
let friend = {
getGreeting() {
return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!";
}
};
// 将原型设置为 person
Object.setPrototypeOf(friend, person);
console.log(friend.getGreeting()); // "Hello, hi!"
console.log(Object.getPrototypeOf(friend) === person); // true
// 将原型设置为 dog
Object.setPrototypeOf(friend, dog);
console.log(friend.getGreeting()); // "Woof, hi!"
console.log(Object.getPrototypeOf(friend) === dog); // true

  在这个示例中,friend对象的getGreeting()方法调用了同名的原型方法。object.getPrototypeOf()方法可以确保调用正确的原型,并向输出字符串叠加另一个字符串;后面的.call(this)可以确保正确设置原型方法中的this值

  要准确记得如何使用Object.getPrototypeOf()方法和call(this)方法来调用原型上的方法实在有些复杂,所以ES6引入了Super关键字。简单来说,Super引用相当于指向对象原型的指针,实际上也就是Object.getPrototypeOf(this)的值。于是,可以这样简化上面的getGreeting()方法

let friend = {
getGreeting() {
// 这相当于上个例子中的:
// Object.getPrototypeOf(this).getGreeting.call(this)
return super.getGreeting() + ", hi!";
}
};

  调用super.getGreeting()方法相当于在当前上下文中调用Object.getPrototypeOf(this).getGreeting.call(this)。同样,可以通过Super引用调用对象原型上所有其他的方法。当然,必须要在使用简写方法的对象中使用Super引用,如果在其他方法声明中使用会导致语法错误

let friend = {
getGreeting: function() {
// 语法错误
return super.getGreeting() + ", hi!";
}
};

  在这个示例中用匿名function定义一个属性,由于在当前上下文中Super引用是非法的,因此当调用super.getGreeting()方法时会抛出语法错误

  Super引用在多重继承情况下非常有用,因为在这种情况下,使用Object.getPrototypeOf()方法将会出现问题

let person = {
getGreeting() {
return "Hello";
}
};
// 原型为 person
let friend = {
getGreeting() {
return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!";
}
};
Object.setPrototypeOf(friend, person);
// 原型为 friend
let relative = Object.create(friend);
console.log(person.getGreeting()); // "Hello"
console.log(friend.getGreeting()); // "Hello, hi!"
console.log(relative.getGreeting()); // error!

  this是relative,relative的原型是friend对象,当执行relative的getGreeting()方法时,会调用friend的getGreeting()方法,而此时的this值为relative。object.getPrototypeOf(this)又会返回friend对象。所以就会进入递归调用直到触发栈溢出报错

  在ES5中很难解决这个问题,但在ES6中,使用Super引用便可以迎刃而解

let person = {
getGreeting() {
return "Hello";
}
};
// 原型为 person
let friend = {
getGreeting() {
return super.getGreeting() + ", hi!";
}
};
Object.setPrototypeOf(friend, person);
// 原型为 friend
let relative = Object.create(friend);
console.log(person.getGreeting()); // "Hello"
console.log(friend.getGreeting()); // "Hello, hi!"
console.log(relative.getGreeting()); // "Hello, hi!"

  Super引用不是动态变化的,它总是指向正确的对象,在这个示例中,无论有多少其他方法继承了getGreeting()方法,super.getGreeting()始终指向person.getGreeting()方法

方法定义

  在ES6以前从未正式定义过"方法"的概念,方法仅仅是一个具有功能而非数据的对象属性。而在ES6中正式将方法定义为一个函数,它会有一个内部的[[HomeObject]]属性来容纳这个方法从属的对象

let person = {
// 方法
getGreeting() {
return "Hello";
}
};
// 并非方法
function shareGreeting() {
return "Hi!";
}

  这个示例中定义了person对象,它有一个getGreeting()方法,由于直接把函数赋值给了person对象,因而getGreetingo方法的[[HomeObject]]属性值为person。而创建shareGreeting()函数时,由于未将其赋值给一个对象,因而该方法没有明确定义[[HomeObject]]属性。在大多数情况下这点小差别无关紧要,但是当使用Super引用时就变得非常重要了

  Super的所有引用都通过[[HomeObject]]属性来确定后续运行过程。第一步是在[[HomeObject]]属性上调用Object.getprototypeof()方法来检索原型的引用,然后搜寻原型找到同名函数,最后设置this绑定并且调用相应方法

let person = {
getGreeting() {
return "Hello";
}
};
// 原型为 person
let friend = {
getGreeting() {
return super.getGreeting() + ", hi!";
}
};
Object.setPrototypeOf(friend, person);
console.log(friend.getGreeting()); // "Hello, hi!"

  调用friend.getGreeting()方法会将person.getGreeting()的返回值与",hi!"拼接成新的字符串并返回。friend.getGreeting()方法的[[HomeObject]]属性值是friend,friend的原型是person,所以super.getGreeting()等价于Person.getGreeting.call(this)

对象遍历

【Object.keys()】

  ES5 引入了Object.keys()方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名

var obj = { foo: 'bar', baz: 42 };
console.log(Object.keys(obj));// ["foo", "baz"]

  ES2017 引入了跟Object.keys配套的Object.valuesObject.entries,作为遍历一个对象的补充手段,供for...of循环使用

let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 }; for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
} for (let value of values(obj)) {
console.log(value); // 1, 2, 3
} for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}

【Object.values()】

  Object.values()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj));// ["bar", 42]

  Object.values()只返回对象自身的可遍历属性

var obj = Object.create({}, {p: {value: 42}});
console.log(Object.values(obj)); // []

  上面代码中,Object.create()方法的第二个参数添加的对象属性(属性p),如果不显式声明,默认是不可遍历的,因为p的属性描述对象的enumerable默认是falseObject.values()不会返回这个属性。只要把enumerable改成trueObject.values就会返回属性p的值

var obj = Object.create({}, {p:
{
value: 42,
enumerable: true
}
});
console.log(Object.values(obj)); // [42]

【Object.entries()】

  Object.entries()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组

var obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj));// [ ["foo", "bar"], ["baz", 42] ]

  除了返回值不一样,该方法的行为与Object.values基本一致

  Object.entries()的基本用途是遍历对象的属性

let obj = { one: 1, two: 2 };
for (let [k, v] of Object.entries(obj)) {
console.log(
`${JSON.stringify(k)}: ${JSON.stringify(v)}`
);
}
// "one": 1
// "two": 2

ES6对象扩展的更多相关文章

  1. ES6(对象扩展)

    ES6(对象(object)新增特性) 1.简介表示法 o,k 为属性:这种为无方法的情况. 这种为有方法. 2.属性表达式 ES6中,[a]就是 b . 3.新增API 1.数组也是引用类型 2.O ...

  2. ES6对象扩展——部分新的方法和属性

    1.Object.is方法返回布尔值,和全等于===差不多,除了参数是+0和-0,以及NaN时 //Object.is,返回布尔值,和全等于===差不多,除了+0和-0,以及NaN console.l ...

  3. ES6 - 对象扩展(增强字面量)

    /** * 对象的扩展 * * 增强对象字面量 * * 解决问题:缩减代码 */ { /** * 1.属性简表示法 * 变量foo直接写在大括号里面.这时,属性名就是变量名, 属性值就是变量值 */ ...

  4. ES6对象扩展——扩展运算符

    1.复制对象:使用扩展运算符复制对象时是浅拷贝 //复制对象:使用扩展运算符复制对象时是浅拷贝 const obj1 = { a:1, b:2, d:{ aa:1, bb:2 } } const ob ...

  5. ES6 对象扩展

    1.属性和变量可以简写 let birth = '2000/01/01'; const Person = { name: '张三', //等同于birth: birth birth, // 等同于he ...

  6. es6对象的扩展

    对象(object)是 JavaScript 最重要的数据结构之一. object 在es6中新增了很多便利的方法 在es6中允许直接写入变量和方法的名称直接作为对象的属性 let x =1 ,y=2 ...

  7. ES6入门之对象扩展

    ES5对象(超类)原有: 属性:construct构造函数 方法: object.hasOwnProperty( propertyName ) //检测是否有一个本地的属性而不是继承的,返回boole ...

  8. es6之函数扩展与对象扩展

    一.函数扩展 1.参数默认值 参数有默认值,后面不可以再加没有默认值的变量.如以下test函数中,不可以加写成 function test(x,y="word",z){ } fun ...

  9. ES6学习之对象扩展

    简介表示法(直接写入变量和函数,作为对象的属性和方法) let x = "test" let obj={ x, //属性名为变量名,属性值为变量值 y(){console.log( ...

随机推荐

  1. 自己积累写的winfrom 操作api 类

    引用 类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...

  2. Bootstrap 常用组件汇总

    Bootstrap 官方文档:http://www.bootcss.com/ Bootstrap Multiselect 多选下拉组件 官方文档:http://www.kuitao8.com/demo ...

  3. Python Trick

    一. 查询函数参数 import inspect print(inspect.getargspec(func)) 二. 查询对象属性 使用 dir() 查询对象属性 使用内置函数 hasattr(ob ...

  4. node.js如何制作命令行工具(一)

    之前使用过一些全局安装的NPM包,安装完之后,可以通过其提供的命令,完成一些任务.比如Fis3,可以通过fis3 server start 开启fis的静态文件服务,通过fis3 release开启文 ...

  5. Django 模型和数据库 总结

    模型和数据库 模型 首先我们在创建一个model的时候,这个类都是继承自 django.db.models.Model, 各种Model Field类型 AutoField,自动增长的IntegerF ...

  6. 【WPF】DispatcherFrame 是个啥玩意儿

    对于 WPF 的线程模型,Dispatcher 对象相信各位大伙伴已经不陌生,尤其是跨线程更新UI的时候,都会用它来调度消息.与 Dispatcher 对象有关的,还有一个叫 DispatcherFr ...

  7. SharePoint 2016 每天预热脚本介绍

    使用SharePoint的朋友们应该知道,SharePoint每天夜里有自动回收的机制,使环境每天把占用的内存都释放出来,以确保不会累计占用过多内存导致服务器崩溃. 我们可以打开IIS,选中我们的应用 ...

  8. JAVA基础——内部类详解

    JAVA内部类详解 在我的另一篇java三大特性的封装中讲到java内部类的简单概要,这里将详细深入了解java内部类的使用和应用. 我们知道内部类可分为以下几种: 成员内部类 静态内部类 方法内部类 ...

  9. JS函数和对象(一)

    在本文章中,将对JS中的函数和对象进行一些讲解,不对之处还请之处 一.JS中的函数 1.1无参函数 其形式如下代码所示 function box(){ alert("我是一个函数,只有被调用 ...

  10. 把本地git仓库中的项目引入到码云上

    一.安装git软件和TortoiseGit客户端(git需配置环境变量,但安装时已经配置好,无需考虑) 二.生成公钥和私钥(建立与码云的连接) 三.在码云上新建项目(建议在组织的基础上)   四.在码 ...