// typeof: 返回的是数据类型的字符串表达形式
//1. 基本类型
var a
console.log(a, typeof a, a===undefined) // undefined 'undefined' true
console.log(a===typeof a) // false
a = 3
console.log(typeof a === 'number')
a = 'atguigu'
console.log(typeof a === 'string')
a = true
console.log(typeof a === 'boolean')
a = null
console.log(a===null) // true
console.log(typeof a) // 'object'
console.log('--------------------------------')
//2. 对象类型
var b1 = {
b2: [2, 'abc', console.log],
b3: function () {
console.log('b3()')
}
}
console.log(b1 instanceof Object, typeof b1) // true 'object'
console.log(b1.b2 instanceof Array, typeof b1.b2) // true 'object'
console.log(b1.b3 instanceof Function, typeof b1.b3) // true 'function'
console.log(typeof b1.b2[2]) // 'function'
console.log(b1.b2[2]('abc')) // 'abc' undefined
添加属性
但是有一些场景不能用
------ xxx.属性名 var p = {}
//1. 给p对象添加一个属性: content type: text/json
// p.content-type = 'text/json' //不能用
p['content-type'] = 'text/json'
console.log(p['content-type'])
//2. 属性名不确定
var propName = 'myAge'
var value = 18
// p.propName = value //不能用
p[propName] = value
console.log(p[propName])
function test(){
this.xxx ="wangxxxxx;
}
var obj={};
test.call(obj);
console.log(obj.xxx);
区别call 和 apply的区别
--call一个或者多个参数
--apply 大于一个参数
定义:
1.定义了
2.但是没有调用
3.最终执行了
常见的回调函数
1.dom事件回调函数==>发生事件的dom元素
2.定时器回调函数=>window.
3.ajax回调函数.
4.生命周期回调函数.
全称: Immediately-Invoked Function Expression
作用:
(function () { //匿名函数自调用
var a = 3
console.log(a + 3)
})()
var a = 4
console.log(a)
;(function () {
var a = 1
function test () {
console.log(++a)
}
window.$ = function () { // 向外暴露一个全局函数
return {
test: test
}
}
})()
$().test() // 1. $是一个函数 2. $执行后返回的是一个对象
函数中的this
function Person(color) {
console.log(this)
this.color = color;
this.getColor = function () {
console.log(this)
return this.color;
};
this.setColor = function (color) {
console.log(this)
this.color = color;
};
}
Person("red"); //this是谁? window
var p = new Person("yello"); //this是谁? p
p.getColor(); //this是谁? p
var obj = {};
p.setColor.call(obj, "black"); //this是谁? obj
var test = p.setColor;
test(); //this是谁? window
function fun1() {
function fun2() {
console.log(this);
}
fun2(); //this是谁? window
}
fun1();
// console.log(Date.prototype.constructor); // ---指向Date函数
// console.log(Date.prototype);
function Fun() {
}
console.log(Fun.prototype);
Fun.prototype.test=function () {
alert('测试数据')
}
var fun = new Fun();
fun.test();
每个函数对象中的prototype对应的空对象
都是实例对象
每个实例对象中都有一个属性__proto__,对应的是函数对象中的prototype中的实例对象.
原型链(图解)
var a = 3 //undefine
function fn () {
console.log(a) //var a=undefine
var a = 4
}
fn() 输出为 undefine
-------------------------------------
console.log(b) //undefined 变量提升
fn2() //可调用 函数提升
// fn3() //不能 变量提升
var b = 3
function fn2() {
console.log('fn2()')
}
var fn3 = function () {
console.log('fn3()')
}
注意:函数提升只能用声明的方式才可以 ,变量式的函数不行.
分为全局代码和函数代码
2.函数执行上下文
创建对应的函数执行上下文对象
(栈中的对象) /*
问题: 结果输出多少?
*/
var x = 10;
function fn() {
console.log(x);
}
function show(f) {
var x = 20;
f();
}
show(fn); --10
作用域与执行上下文
确定之后
, js代码马上执行之前创建作用域链
闭包的条件
function fn1 () {
var a = 2
var b = 'abc'
function fn2 () { //执行函数定义就会产生闭包(不用调用内部函数)
console.log(a)
}
// fn2()
}
fn1()
常见的的闭包
1.将函数作为另外一个函数的返回值
function f1(){
var a=3;
function f2(){
a++ //产生闭包
console.log(a)
}
return f2
}
var t=f1() //函数执行完后,进行释放,但是函数内部的变量依然存在可以进行使用
t(); 4
t(); 5
2.将参数作为实参传递给另外函数调用
function showDelog(msg,time){
setTimeout(function () {
alert(msg);
},time)
}
showDelog('显示数据',2000);
闭包的作用
1.函数执行完后,函数内部声明的局部变量是否还存在? 一般不存在,存在于函数内部的闭包可能存在
2.函数外部能够访问到函数的局部变量吗? 不能,但是我们可以通过闭包去访问.
function f1(){ //执行函数时,闭包产生
var a=3;
function f2(){
a++ //产生闭包
console.log(a)
}
return f2
}
var t=f1()
t(); 4
t(); 5
t=null //当调用函数对象没人调用时,变为垃圾对象时闭包就死亡了.
第一种方式:
(function () {
var msg='mybatis';
function f1() {
console.log(msg)
}
window.moudle={
f1:f1
}
})()
第二种方式:
function f1() {
var msg='mybatis';
function f2() {
console.log(msg)
}
return f2
}
var t=f1()
t(); //执行闭包
function f1(){
a=3 //1.意外的全局变量
}
f1();
var intervalId= setInterval(function(){
console.log('--------')
},1000) //2.计时器没来得及清除
clearInterval(intervalId);
function fn1() {
var a = 4
function fn2() {
console.log(++a) // 3. 闭包
}
return fn2
}
var f = fn1()
f()
var t=new Object()
t.name='xxx'
t.age=12
t.setName=function (name) {
this.name=name
}
console.log(t.name,t.age)
t.setName('bob')
console.log(t.name,t.age)
var obj={
name:'xxxx',
age:12,
setName :function (name) {
this.name=name
}
}
console.log(obj.name,obj.age)
obj.setName('wx')
console.log(obj.name,obj.age)
function createPerson(name ,age){
var obj={
name:name,
age:age,
setName:function (name) {
this.name=name
}
}
return obj;
}
var person1=createPerson('xxxx',12);
var person2=createPerson('bbbb',18);
function Person(name,age) {
this.name=name;
this.age=age;
this.setName=function (name) {
this.name=name
}
}
var p1=new Person('wx',18);
p1.setName('bob')
console.log(p1.name,p1.age);
console.log(p1 instanceof Person)
function Person(name ,age){
this.name=name
this.age=age
}
Person.prototype.setName= function (name) {
this.name =name
}
var p1 =new Person('xxx',18);
p1.setName('xxx1')
var p2=new Person('bob',20);
p2.setName('bob1')
console.log(p1.name,p1.age)
console.log(p2.name,p2.age)
//父类型
function Supper() {
this.supProp = 'Supper property'
}
Supper.prototype.showSupperProp = function () {
console.log(this.supProp)
}
//子类型
function Sub() {
this.subProp = 'Sub property'
}
//子类型的显示原型为父类的实例对象 --
Sub.prototype = new Supper()
// 让子类型的原型的constructor指向子类型
Sub.prototype.constructor=Sub
其实就是调用call
function Supper(name ,age){
this.name =name
this.age =age
}
function Sub(name,age,price){
Supper.call(this,name,age) //相当于 创建对象的t t.Supper(name ,age) ----t.name ,t.age
this.price=price
}
var t=new Sub('wwd',18,120)
console.log(t.name,t.age,t.price);
继承分为两种 ,一种是原型链继承,一种是借用构造函数继承。原型链主要是用来继承prototype的方法,而借用构造函数主要继承的是属性。所有需要结合两种方式的去实现继承。
function Person(name ,age){
this.name =name
this.age=age
}
Person.prototype.setName =function (name) {
this.name=name
}
//借用构造函数继承
function Student(name ,age, price) {
Person.call(this,name,age)
this.price=price
}
//原型链继承
Student.prototype =new Person()
Student.prototype.constructor=Student
var t=new Student('wwd',18,1000)
t.setName('wwd1')
console.log(t.name,t.age,t.price);