MXOXW

Life always finds a way.

修改cmd字体

| Comments

在终端、cmd、编辑器中偶尔会有中文字符出现,Windows下默认的点阵字体「宋体」和等宽英文字符放在一起非常违和。一个解决方法是下载混合字体,比如「Consolas + YAHEI hybrid」,「Source Code Pro + YAHEI hybrid」。但是这些字体组合毕竟有限,如果想用「Anonymous Pro + 幼圆」、或者更改字重、使用斜体该怎么办呢?这时便要用到注册表的FontLink功能了。

FontLink,顾名思义,是将某个字体未包含的字符映射到另一个字体上。比如编辑器中设定默认字体是「Consolas」,如果文件中有汉字字符,Windows本来默认显示为「宋体」,但是FontLink设置了「雅黑」,便可以用「雅黑」来显示。

以「Consolas + 雅黑」为例,下面是实现方法:

按下Win+R打开「运行」,输入regedit点击确定,开启「注册表」;
定位到如下位置;

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
找到Consolas项,双击打开,在「数值数据」文本框内输入以下内容后点击确定;

1
2
MSYH.TTF,192,154
MSYH.TTF

192,154在font-size=12或14时,中文对齐比较整洁
注销或重启计算机。

使用注册表优化终端、编辑器的中英字体混合显示,如「Consolas + 雅黑」 - SegmentFault
让你的windows控制台更♂诱♂人_论野生技术与二次元

附件:
FontLink.reg

JavaScript 权威指南-类和模块

| Comments

9.1 类和原型
9.2 类和构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* A Range class using a constructor
*/
// range2.js: Another class representing a range of values.
// This is a constructor function that initializes new Range objects.
// Note that it does not create or return the object. It just initializes this.
function Range(from, to) {
// Store the start and end points (state) of this new range object.
// These are noninherited properties that are unique to this object.
this.from = from;
this.to = to;
}
// All Range objects inherit from this object.
// Note that the property name must be "prototype" for this to work.
Range.prototype = {
// Return true if x is in the range, false otherwise
// This method works for textual and Date ranges as well as numeric.
includes: function(x) {
return this.from <= x && x <= this.to;
},
// Invoke f once for each integer in the range.
// This method works only for numeric ranges.
foreach: function(f) {
for (var x = Math.ceil(this.from); x <= this.to; x++) f(x);
},
// Return a string representation of the range
toString: function() {
return "(" + this.from + "..." + this.to + ")";
}
};
// Here are example uses of a range object
var r = new Range(1, 3); // Create a range object
r.includes(2); // => true: 2 is in the range
r.foreach(console.log); // Prints 1 2 3
console.log(r); // Prints (1...3)

9.2.2 constructor属性

9.4 类的扩充
JavaScript中基于原型的继承机制是动态的:对象从其原型继承属性,如果创建对象之后原型的属性发生改变,也会影响到继承这个原型的所有实例对象。这意味着我们可以通过给原型对象添加新方法来扩充JavaScript类。

1
2
3
4
5
6
7
8
9
10
11
12
// Define the ES5 String.trim() method if one does not already exist.
// This method returns a string with whitespace removed from the start and end.
String.prototype.trim = String.prototype.trim || function() {
if (!this) return this; // Don't alter the empty string
return this.replace(/^\s+|\s+$/g, ""); // Regular expression magic
};
// Return a function's name. If it has a (nonstandard) name property, use it.
// Otherwise, convert the function to a string and extract the name from that.
// Returns an empty string for unnamed functions like itself.
Function.prototype.getName = function() {
return this.name || this.toString().match(/function\s*([^(]*)\(/)[1];
};

9.5 类和类型
9.5.1 instanceof
instanceof运算符和isPrototypeOf()方法的缺点是,我们无法通过对象来获得类名,只能检测对象是否属于指定的类名。在客户端JavaScript中还有一个比较严重的不足,就是在多窗口和多框架子页面的Web应用中兼容性不佳。每个窗口和框架子页面都具有单独的执行上下文,每个上下文都包含独有的全局变量和一组构造函数。在两个不同框架页面中创建的两个数组继承自两个相同但相互独立的原型对象,其中一个框架页面中的数组不是另一个框架页面的Array()构造函数的实例,instanceof运算结果是false。

JavaScript 权威指南-函数

| Comments

8.1 函数定义

  • 函数表达式
  • 函数声明式

8.2 函数调用

  • 作为函数
  • 作为方法
  • 作为构造函数
  • 通过它们的call()和apply()方法间接调用

8.3 函数的实参和形参

8.3.1 可选形参
传入的实参比形参个数少,剩余的形参置为undefined。

8.3.2 实参对象
arguments指向实参对象的引用,是一个类数组对象
callee:当前正在执行的函数
caller(非标准的):调用当前正在执行的函数的函数

8.6 闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var scope = "global scope"; // A global variable
function checkscope() {
var scope = "local scope"; // A local variable
function f() {
return scope;
} // Return the value in scope here
return f;
}
checkscope()() // What does this return?

/**
*
*/
function counter() {
var n = 0;
return {
count: function() {
return n++;
},
reset: function() {
n = 0;
}
};
}
var c = counter(),
d = counter(); // Create two counters
c.count() // => 0
d.count() // => 0: they count independently
c.reset() // reset() and count() methods share state
c.count() // => 0: because we reset c
d.count() // => 1: d was not reset

JavaScript 权威指南-数组

| Comments

##7.8数组方法

  • join()

    1
    2
    3
    4
    5
    6
    var a = [1, 2, 3];          // Create a new array with these three elements
    a.join(); // => "1,2,3"
    a.join(" "); // => "1 2 3"
    a.join(""); // => "123"
    var b = new Array(10); // An array of length 10 with no elements
    b.join('-') // => '---------': a string of 9 hyphens
  • reverse()

    1
    2
    var a = [1,2,3];
    a.reverse().join() // => "3,2,1" and a is now [3,2,1]
  • sort()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    var a = new Array("banana", "cherry", "apple");
    a.sort();
    var s = a.join(", "); // s == "apple, banana, cherry"

    /**
    * [a description]
    * @type {Array}
    */
    var a = [33, 4, 1111, 222];
    a.sort(); // Alphabetical order: 1111, 222, 33, 4
    a.sort(function(a, b) { // Numerical order: 4, 33, 222, 1111
    Core JavaScript
    return a - b; // Returns &lt; 0, 0, or &gt; 0, depending on order
    });
    a.sort(function(a, b) {
    return b - a
    }); // Reverse numerical order

    /**
    * [a description]
    * @type {Array}
    */
    a = ['ant', 'Bug', 'cat', 'Dog']
    a.sort(); // case-sensitive sort: ['Bug','Dog','ant',cat']
    a.sort(function(s, t) { // Case-insensitive sort
    var a = s.toLowerCase();
    var b = t.toLowerCase();
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
    }); // => ['ant','Bug','cat','Dog']
  • concat()

    1
    2
    3
    4
    5
    var a = [1,2,3];
    a.concat(4, 5) // Returns [1,2,3,4,5]
    a.concat([4,5]); // Returns [1,2,3,4,5]
    a.concat([4,5],[6,7]) // Returns [1,2,3,4,5,6,7]
    a.concat(4, [5,[6,7]]) // Returns [1,2,3,4,5,[6,7]]
  • slice()

    1
    2
    3
    4
    5
    var a = [1,2,3,4,5];
    a.slice(0,3); // Returns [1,2,3]
    a.slice(3); // Returns [4,5]
    a.slice(1,-1); // Returns [2,3,4]
    a.slice(-3,-2); // Returns [3]
  • splice()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /**
    * 第一个参数指定插入和(或)删除的起始位置
    * 第二个参数指定应该从数组删除元素的个数,如果省略,从起始到数组结尾的所有元素都将删除
    * 第三个开始之后的参数指定插入到起始位置的元素
    * 返回由删除元素组成的数组,没有元素删除返回空数组
    */
    var a = [1,2,3,4,5,6,7,8];
    a.splice(4); // Returns [5,6,7,8]; a is [1,2,3,4]
    a.splice(1,2); // Returns [2,3]; a is [1,4]
    a.splice(1,1); // Returns [4]; a is [1]

    var a = [1,2,3,4,5];
    a.splice(2,0,'a','b'); // Returns []; a is [1,2,'a','b',3,4,5]
    a.splice(2,2,[1,2],3); // Returns ['a','b']; a is [1,2,[1,2],3,3,4,5]
  • push() and pop()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var stack = [];         // stack: []
    stack.push(1,2); // stack: [1,2] Returns 2
    stack.pop(); // stack: [1] Returns 2
    Core JavaScript
    stack.push(3); // stack: [1,3] Returns 2
    stack.pop(); // stack: [1] Returns 3
    stack.push([4,5]); // stack: [1,[4,5]] Returns 2
    stack.pop() // stack: [1] Returns [4,5]
    stack.pop(); // stack: [] Returns 1
  • unshift() and shift()

    1
    2
    3
    4
    5
    6
    7
    8
    var a = [];             // a:[]
    a.unshift(1); // a:[1] Returns: 1
    a.unshift(22); // a:[22,1] Returns: 2
    a.shift(); // a:[1] Returns: 22
    a.unshift(3,[4,5]); // a:[3,[4,5],1] Returns: 3
    a.shift(); // a:[[4,5],1] Returns: 3
    a.shift(); // a:[1] Returns: [4,5]
    a.shift(); // a:[] Returns: 1

##7.9 ECMAScript 5 数组方法
大多数方法的第一个参数接收一个函数,并且对数组的每个元素(或一些元素)调用一次该函数。如果是稀疏数组,对不存在的元素不调用传递的函数。在大多数情况下,调用提供的函数使用三个参数:数组元素、元素的索引和数组本身。通常,只需要第一个参数值,可以忽略后两个参数.大多数ECMAScript 5数组方法的第一个参数是一个函数,第二个参数是可选的。如果有第二个参数,则调用的函数被看做是第二个参数的方法。也就是说,在调用函数时传递进去的第二个参数作为它的this关键字的值来使用。被调用的函数的返回值非常重要,但是不同的方法处理返回值的方式也不一样。ECMAScript 5中的数组方法都不会修改它们调用的原始数组。当然,传递给这些方法的函数是可以修改这些数组的。

  • forEach()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    var data = [1, 2, 3, 4, 5]; // An array to sum
    // Compute the sum of the array elements
    var sum = 0; // Start at 0
    data.forEach(function(value) {
    sum += value;
    }); // Add each value to sum
    sum // => 15
    // Now increment each array element
    data.forEach(function(v, i, a) {
    a[i] = v + 1;
    });
    data // => [2,3,4,5,6]

    /**
    * **break问题**
    */
    function foreach(a, f, t) {
    try {
    a.forEach(f, t);
    }
    catch (e) {
    if (e === foreach.break) return;
    else throw e;
    }
    }
    foreach.break = new Error("StopIteration");
  • map()
    传递给map()的函数的调用方式和传递给于forEach的函数的调用方式一样。但传递给map()的函数应该有返回值。注意map()返回的是新数组:它不修改调用的数组。如果是稀疏数组,返回的也是相同方式的稀疏数组:它具有相同的长度,相同的缺失元素。

    1
    2
    a = [1, 2, 3];
    b = a.map(function(x) { return x*x; }); // b is [1, 4, 9]
  • filter()

    1
    2
    3
    4
    5
    6
    7
    a = [5, 4, 3, 2, 1];
    smallvalues = a.filter(function(x) { return x < 3 }); // [2, 1]
    everyother = a.filter(function(x,i) { return i%2==0 }); // [5, 3, 1]

    var dense = sparse.filter(function() { return true; });

    a = a.filter(function(x) { return x !== undefined && x != null; });
  • every() and some()
    数组逻辑判定

    1
    2
    3
    4
    5
    6
    7
    8
    a = [1,2,3,4,5];
    a.every(function(x) { return x < 10; }) // => true: all values < 10.
    a.every(function(x) { return x % 2 === 0; }) // => false: not all values even.


    a = [1,2,3,4,5];
    a.some(function(x) { return x%2===0; }) // => true a has some even numbers.
    a.some(isNaN) // => false: a has no non-numbers.
  • reduce() and reduceRight()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var a = [1,2,3,4,5]
    var sum = a.reduce(function(x,y) { return x+y }, 0); // Sum of values
    var product = a.reduce(function(x,y) { return x*y }, 1); // Product of values
    var max = a.reduce(function(x,y) { return (x>y)?x:y; }); // Largest value

    var a = [2, 3, 4]
    // Compute 2^(3^4). Exponentiation has right-to-left precedence
    var big = a.reduceRight(function(accumulator,value) {
    return Math.pow(value,accumulator);
    });
  • indexOf() and lastIndexOf()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    a = [0,1,2,1,0];
    a.indexOf(1) // => 1: a[1] is 1
    a.lastIndexOf(1) // => 3: a[3] is 1
    a.indexOf(3) // => -1: no element has value 3

    /**
    * 在数组中查找所有出现的x,并返回一个包含匹配索引的数组
    */
    function findall(a, x){
    var results = [], //将会返回的数组
    len = a.length, //待搜索数组的长度
    p05 = 0; //开始搜索的位置
    while (pos < len) { //循环搜索多个元素…
    pos = a.indexOf(x, pos); //搜索
    if (pos === -1) break; //未找到,就完成搜索
    results.push(pos); //否则,在数组中存储索引
    pos = pos + 1; //并从下一个位置开始搜索
    }
    return results; //返回包含索引的数组
    }

JavaScript 权威指南-对象

| Comments

##6.4检测属性

  • in运算符
  • hasOwnProperty()检测是否是对象自有属性
  • propertyIsEnumerable()是hasProperty()的增强版,只有检测到是自有属性且这个属性的enumerable为true时才返回true。
  • !==判断属性是否undefined(in可以区分不存在的属性和存在但是值为undefined的属性)
1
2
3
4
5
6
7
var o = { x: undefined } // Property is explicitly set to undefined
o.x !== undefined // false: property exists but is undefined
o.y !== undefined // false: property doesn't even exist
"x" in o // true: the property exists
"y" in o // false: the property doesn't exists
delete o.x; // Delete the property x
"x" in o // false: it doesn't exist anymore

##6.7属性特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Object.getOwnPropertyDescriptor({x:1}, "x");    //获得某个对象特定属性的属性描述符
//Object.getPrototypeOf()

var o = {}; // Start with no properties at all
// Add a nonenumerable data property x with value 1.
Object.defineProperty(o, "x", { value : 1,
writable: true,
enumerable: false,
configurable: true});
// Check that the property is there but is nonenumerable
o.x; // => 1
Object.keys(o) // => []
// Now modify the property x so that it is read-only
Object.defineProperty(o, "x", { writable: false });
// Try to change the value of the property
o.x = 2; // Fails silently or throws TypeError in strict mode
o.x // => 1
// The property is still configurable, so we can change its value like this:
Object.defineProperty(o, "x", { value: 2 });
o.x // => 2
// Now change x from a data property to an accessor property
Object.defineProperty(o, "x", { get: function() { return 0; } });
o.x // => 0

/**
同时修改或者创建多个属性
**/
var p = Object.defineProperties({}, {
x: { value: 1, writable: true, enumerable:true, configurable:true },
y: { value: 1, writable: true, enumerable:true, configurable:true },
r: {
get: function() { return Math.sqrt(this.x*this.x + this.y*this.y) },
enumerable:true,
configurable:true
}
});