目录
this关键字
this`关键字是一个非常重要的语法点。毫不夸张地说,不理解它的含义,大部分开发任务都无法完成。
this
可以用在构造函数之中,表示实例对象。除此之外,this
还可以用在别的场合。但不管是什么场合,this
都有一个共同点:它总是返回一个对象。
简单说,this
就是属性或方法“当前”所在的对象。
var person = {
name: '张三',
describe: function () {
return '姓名:'+ this.name;
}
};person.describe()
// "姓名:张三"
上面代码中,this.name
表示name
属性所在的那个对象。由于this.name
是在describe
方法中调用,而describe
方法所在的当前对象是person
,因此this
指向person
,this.name
就是person.name
。
由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this
的指向是可变的
this指向
function f() {
return '姓名:'+ this.name;
}var A = {
name: '张三',
describe: f
};var B = {
name: '李四',
describe: f
};A.describe() // "姓名:张三"
B.describe() // "姓名:李四"
上面代码中,函数f
内部使用了this
关键字,随着f
所在的对象不同,this
的指向也不同。
只要函数被赋给另一个变量,this
的指向就会变。
var f = function () {
console.log(this.x);
}var x = 1;
var obj = {
f: f,
x: 2,
};// 单独执行
f() // 1// obj 环境执行
obj.f() // 2
不同环境下运行,this的指向也不同
构造函数this指向
var Obj = function (p) { this.p = p; };
上面代码定义了一个构造函数Obj
。由于this
指向实例对象,所以在构造函数内部定义this.p
,就相当于定义实例对象有一个p
属性。this指的是o。
var o = new Obj('Hello World!'); o.p // "Hello World!"
prototype(原型)
constructor属性
prototype
对象有一个constructor
属性,默认指向prototype
对象所在的构造函数。
由于constructor
属性定义在prototype
对象上面,意味着可以被所有实例对象继承
function P() {}
var p = new P();
p.constructor === P // truep.constructor === P.prototype.constructor // true
p.hasOwnProperty('constructor') // false
instanceof
instanceof运算符返回一个布尔值,表示对象是否为某个构造函数的实例
var v = new Vehicle();
v instanceof Vehicle // true
instanceof运算符的一个用处,是判断值的类型
var x = [1, 2, 3];
var y = {};
x instanceof Array // true
y instanceof Object // true
利用instanceof
运算符,还可以巧妙地解决,调用构造函数时,忘了加new
命令的问题。
function Fubar (foo, bar) {
if (this instanceof Fubar) {
this._foo = foo;
this._bar = bar;
} else {
return new Fubar(foo, bar);
}
}
prototype和__proto__区别是什么
参照如下代码
function Foo() {
this.bar = 1
}Foo.prototype.show = function show() {
console.log(this.bar)
}let foo = new Foo()
foo.show()
我们可以认为原型prototype
是类Foo
的一个属性,而所有用Foo
类实例化的对象,都将拥有这个属性中的所有内容,包括变量和方法。比如上图中的foo
对象,其天生就具有foo.show()
方法。
我们可以通过Foo.prototype
来访问Foo
类的原型,但Foo
实例化出来的对象,是不能通过prototype访问原型的。这时候,就该__proto__
登场了。
一个Foo类实例化出来的foo对象,可以通过foo.__proto__
属性来访问Foo类的原型,也就是说:
foo.__proto__ == Foo.prototype
总结一下:
prototype
是一个类的属性,所有类对象在实例化的时候将会拥有prototype
中的属性和方法- 一个对象的
__proto__
属性,指向这个对象所在的类的prototype
属性
dns记录类型
域名与IP之间的对应关系,称为"记录"(record)。根据使用场景,"记录"可以分成不同的类型(type)。
常见的DNS记录类型如下。
(1) A:地址记录(Address),返回域名指向的IP地址。
(2) NS:域名服务器记录(Name Server),返回保存下一级域名信息的服务器地址。该记录只能设置为域名,不能设置为IP地址。
(3)MX:邮件记录(Mail eXchange),返回接收电子邮件的服务器地址。
(4)CNAME:规范名称记录(Canonical Name),返回另一个域名,即当前查询的域名是另一个域名的跳转,详见下文。
(5)PTR:逆向查询记录(Pointer Record),只用于从IP地址查询域名,详见下文
闭包
在JS中,通俗来讲,闭包就是能够读取外层函数内部变量的函数。
读取函数内部的局部变量
在函数内部再定义一个函数
function f1() { let code = 200; function f2() { console.log(code); } }
函数f1内部的函数f2可以读取f1中所有的局部变量。因此,若想在外部访问函数f1中的局部变量code
,可通过函数f2间接访问
为外部程序提供访问函数局部变量的入口
function f1() { let code = 200; function f2() { console.log(code); } return f2; } f1()(); // 200
闭包概念
上个例子中的函数f2,就是闭包,其作用就是将函数内部与函数外部进行连接。
闭包访问的变量,是每次运行上层函数时重新创建的,是相互独立的。
不同的闭包,可以共享上层函数中的局部变量