JavaScript学习--02

@JavaScript和java的关系?以及版本更迭?JavaScript、ES6、typescript、ECMAScript
JavaScript与java 没有关系。JavaScript是一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。
ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,他往往被称为JavaScript或JScript。ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现。
TypeScript是一种由微软开发的自由和开源的编程语言。他是JavaScript的一个超集,而且本质上想这个语言添加了可选的静态类型和基于类的面向对象编程。TypeScript最大的特点就是类型化,更加容易维护。
ES6:ECMAScript6.0是JavaScript语言的下一代标准,已经在2015年6月正式发布。他的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
ES6新特征:
ES6中的let命令,声明变量、用法和var差不多,但是let是为JavaScript新增了块级作用域,ES5中时没有块级作用域的,并且var有变量提升的概念,但是在let中,使用的变量一定要进行声明。
ES6不再像ES5一样使用原型链实现继承,而是引用class这个概念。
ES6中的函数定义也不再使用关键字function,而是利用了 => 来进行定义
ES6中可以设置默认函数参数
TypeScript是JavaScript的超集,实现以面向对象编程的方式使用JavaScript。
完整的JavaScript包含三个部分:ECMAScript、

@JavaScript的数据类型?常用的类型有哪些?
JavaScript的数据类型分为两大类:原始数据类型和引用数据类型
原始数据类型:
object、number、string、Boolean、null、undefined
引用数据类型:
object类型的Array、Date、function
变量:弱类型语言。声明的时候没有统一的变量的声明(使用Var关键字声明)。
ES6使用 let和const 声明
java中变量的作用域通过 { } 决定。JavaScript通过一个方法体来确定一个作用域(函数)。
变量的作用范围:由函数体决定的(和java不同)。ES6使用let声明变量的作用域和java类型一样。

@JavaScript中常用的数据类型有哪些?声明情况下被使用到?
JavaScript的数据类型分为两大类:原始数据类型和引用数据类型
原始数据类型:
object、number、string、Boolean、null、undefined
引用数据类型:
object类型的Array、Date、function
typeof可以检测数据类型。

@undefined和null的区别?各在声明情况下使用?
null是JavaScript中的关键字,表示控制,null可以看做是object的一个特殊值,如果一个object值为空,表示这个对象不是有效对象。
undefined不是JavaScript中的关键字,其实一个全局变量。
区别:
1. 类型不一样。null是JavaScript语言的关键字,undefined是JavaScript预定义的全局变量。
2. 转化为值时不一样:undefined为NaN,null为0
3. undefined===null;//false
undefined ==null; //true
4. null是不存在,undefined是错误、不明确、未定义。
5. 执行typeof运算,null返回“object”字符串,undefined返回“undefined”字符串。

undefined和null在if语句中,都会被自动转为false,相等运算符直接报告两者相等,他们都不属于任何属性和方法。在根据需要转换成对象时两者都会报异常。

undefined:表示缺少值,就是此处应该有一个值,但是还没有定义。
变量被声明了,但是没有赋值时,就等于undefined
调用函数时,应该提供的参数没有提供,该参数等于undefined
要查询的对象属性或数组的元素不存在时,该属性的值为undefined
函数没有返回值时,默认返回undefined
null:表示没有对象,即该处不应该有值。
作为函数的参数,表示该函数的参数不是对象
作为对象原型链的重点

运算符:算术运算、比较运算、位运算、逻辑运算(逻辑短路)、
程序语句:顺序、分支、循环、分支流程(if、if-else、if-elseif-else、switch语句(支持数值、字符串))、循环流程(for循环、while循环、do-while循环)

函数:
函数的定义、声明:不需要声明返回值类型,直接返回即可,默认返回undefined类型
函数的返回值:return返回、函数的返回值还可以是一个函数对象
函数的参数

@函数的声明方式有哪些?

function funName(){ //函数体}
​
var funcName1 = function name(){
    ]console.log("函数体");
}
funcName1();
    
var funcName2 = new Function();

@函数的返回值如何处理?
如果函数中没有return关键字,那么函数有默认的返回值undefined
如果函数中有return关键字,那么这个关键字后面的代码是不会执行的
如果函数中有return关键字,这个关键字后面没有值,那么这个函数有返回值是undefined
如果函数中有return关键字,这个关键字后面有值,那么这个值就是这个函数的返回值。

@函数调用之间的返回值?默认为undefined类型。函数的传参形式?
ECMAScript中所有函数的参数都是按值传递的
把函数外部的值赋值给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样。而引用类型值的传递,则如同引用类型变量的复制一样。

异常处理:try-catch-finally异常处理

@JavaScript有异常处理吗?常用的异常处理有哪些?
try块:
try块包含的是可能产生异常的代码,在这里面直接或者在里面通过调用函数里间接抛出的异常都可以捕获到。
catch块:
catch块是捕获异常,并处理异常的地方,包括条件捕获和非条件捕获。
catch(e instanceof obj) 用instanceof判断异常的对象类型,实现指定的异常处理方式 。
catch(e) 当异常抛出时,无论异常的类型都进行捕获并处理。
//条件捕获与非条件捕获

try {
    throw new Err();
}catch(e instanceof ErrBob) {
    console.log(e.name + ' Bob'');
}catch(e instanceof ErrTom) {
    console.log(e.name + ' Tom'');
}catch(e instanceof ErrLily) {
    console.log(e.name + ' Lily'');
}catch(e) {
    console.log('that's all');
}

finally块:
无论是否捕获异常,都会在try或catch块后立即执行。finally块常常用以文件的关闭,标记的取消等操作。
JavaScript的异常出现以后,会触发错误事件传递给window对象,可以使用:window.onerror = function() { } 来抓捕页面上的每一个错误。

@JavaScript是否支持面向对象的吗?如何创建一个类?

支持面向对象,并不是完全的面向对象

  1. 对象字面量: 创建多个对象会出现大量重复的代码
var person1 = {
    name: "bai",
    age : 29,
    job: "Software Engineer",
    sayName: function(){
        alert(this.name);
    }
};
  1. 工厂模式:该模式抽象了创建具体对象的过程,用函数来封装以待定接口创建对象的区别,但是没有解决对象识别的问题。
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('bai',29,'software Engineer');
var person2 = createPerson('hu',25,'software Engineer');
  1. 构造函数模式:通过自定义的构造函数,来定义自定义对象类型的属性和方法。创建自定义的构造函数意味着可以将它的实例表示为一种特定的类型。该模式没有显式的创建对象,直接将属性和方法赋给了this对象,且没有return语句。但是构造函数模式的问题在于每个方法在每个实例上重新创建一遍,创建多个完成相同任务的方法完全没有必要,浪费内存空间。
function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.jog = job;
    this.sayName = function(){
        alert(this.name);
    };
}
var person1 = new Person("bai",29,"software Engineer");
var person2 = new Person("hu",25,"software Engineer");
//具有相同作用的sayName()方法在person1和person2这两个实例中却占用了不同的内存空间
console.log(person1.sayName === person2.sayName);//false
​
//将方法定义转移到构造函数外部,可以解决方法被重复创建的问题
function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.jog = job;
    this.sayName = sayName;
}
function sayName(){
    alert(this.name);
};
var person1 = new Person("bai",29,"software Engineer");
var person2 = new Person("hu",25,"software Engineer");
console.log(person1.sayName === person2.sayName);//true
  1. 寄生构造函数模式:该模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。该模式是工厂模式和构造函数模式的结合。该模式存在的问题是每个方法都要在每个实例上重新创建一遍,浪费内存空间。该模式返回的对象与构造函数之间没有关系,因此使用instanceof运算符和prototype属性都是没有意义的。
function Person(name,age,job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        console.log(this.name);
    };
    return o;
}
var person1 = new Person("bai",29,"software Engineer");
var person2 = new Person("hu",25,"software Engineer");
//具有相同作用的sayName()方法在person1和person2这两个实例中却占用了不同的内存空间
console.log(person1.sayName === person2.sayName);//false
console.log(person1 instanceof Person);//false
console.log(person1.__proto__ === Person.prototype);//false
  1. 稳妥的构造函数模式:没有公共属性,而且其方法也不引用this的对象,稳妥对象最适合在一些安全环境中或者在防止数据被其他应用程序改动时使用。稳妥构造函数与寄生构造函数模式相似,但是稳妥构造函数新创建对象的实例方法不引用this,并且不能用new操作符调用构造函数。
function Person(name,age,job){
    //创建要返回的对象
    var o = new Object();
    //可以在这里定义私有变量和函数
    //添加方法
    o.sayName = function(){
        console.log(name);
    };
    //返回对象
    return o;
}
//在稳妥模式创建的对象中,除了使用sayName()方法之外,没有其他方法访问name的值
var friend = Person("bai",29,"Software Engineer");
friend.sayName();//"bai"
  1. 原型模式:原型对象可以让所有实例共享他的属性和方法,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到圆形对象中。
function Person(){
    Person.prototype.name = "bai";
    Person.prototype.age = 29;
    Person.prototype.job = "software Engineer";
    Person.prototype.sayName = function(){
        console.log(this.name);
    }
}
var person1 = new Person();
person1.sayName();//"bai"
var person2 = new Person();
person2.sayName();//"bai"
alert(person1.sayName == person2.sayName);//true
  1. 更简单的原型模式:减少了不必要的输入,用一个包含所有属性和方法的对象字面量来重写整个原型对象。但是经过对象字面量的改写,constructor不再指向Person,使得Person.prototype的自有属性constructor属性不存在,只有从原型链中找到Object.prototype中的constructor属性,或者可以显式的设置原型对象的constructor属性。圆形模式问题在于引用类型值属性会被所有的实例对象共享并修改。
function Person(){};
Person.prototype = {
    name: "bai",
    age: 29,
    job: "software Engineer",
    sayName : function(){
        console.log(this.name);
    }
};
var person1 = new Person();
person1.sayName();//"bai"
console.log(person1.constructor === Person);//false
console.log(person1.constructor === Object);//true
​
//显式设置原型对象的constructor属性
function Person(){};
Person.prototype = {
    //constructor: Person,或者适用这种方法设置constructor属性
    name: "bai",
    age: 29,
    job: "software Engineer",
    sayName : function(){
        console.log(this.name);
    }
};
Object.defineProperty(Person.prototype,'constructor',{
    enumerable: false,
    value: Person
});
var person1 = new Person();
person1.sayName();//"bai"
console.log(person1.constructor === Person);//true
console.log(person1.constructor === Object);//false

8.组合模式:组合使用构造函数模式和原型模式是创建自定义类型的最常见方式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性,这种组合模式还支持想构造函数传递采纳数。实例对象都有自己的一份实例属性的副本,同时又共享对方法的引用,最大限度的节省了内存。该模式是目前适用最广泛认同度最高的一种创建自定义对象的模式。

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["shelby","Court"];
}
Person.prototype = {
    constructor: Person,
    sayName : function(){
        console.log(this.name);
    }    
}
var person1 = new Person("bai",29,"Software Engineer");
var person2 = new Person("hu",25,"Software Engineer");
person1.friends.push("Van");
alert(person1.friends);// ["shelby","Court","Van"];
alert(person2.friends);// ["shelby","Court"];
alert(person1.friends === person2.friends);//false
alert(person1.sayName === person2.sayName);//true
  1. 动态原型模式:动态原型模式将组合模式中分开适用的构造函数和原型对象都封装到了构造函数中,然后通过检查方法是否被创建,来决定是否初始化原型对象。如果原型对象中包含多个语句,只需要奸恶其中一个语句即可。
function Person(name,age,job){
    //属性
    this.name = name;
    this.age = age;
    this.job = job;
    //方法
    if(typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            console.log(this.name);
        };
    }
}
var friend = new Person("bai",29,"Software Engineer");
friend.sayName();//'bai'

@JavaScript如何实现类的继承?
类式继承:通过构造函数来实现继承

//父类
function Parent(name) {
  this.name = name || "parent";
}
Parent.prototype.say = function() {
  return this.name;
}
​
//子类
function Child() {}
  1. 父类对象继承:使用这种继承模式,子类不仅仅会继承父类原型上的方法/属性,还会继承父类自身的属性。
Child.prototype = new Parent("child");
​
var child = new Child();
child.say(); // "child"
  1. 借用构造函数:改造子类,子类只会继承父类自身的属性。他无法从原型链中继承任何方法或属性
function Child(){
  Parent.apply(this, arguments);
}
  1. 共享原型:子类原型和父类原型共享一个对象,那么子类如果修改原型,必然会影响父类。
    Child.prototype = Parent.prototype;

  2. 临时构造函数:利用一个空函数F()充当紫烈和父类之间的代理,既可以实现父类原型方法或属性的继承,又可以在子类原型上基础扩展方法或属性。一般可以使用object.create()来实现此类继承。

function inherit(Child, Parent) {
  var F = function(){};
  F.prototype = Parent.prototype;
  Child.prototype = new F();
}
Child.prototype = Object.create(Parent.prototype);

通过复制属性实现继承
复制属性分为浅拷贝和深拷贝。浅拷贝不会复制对象类型,只会简单的将对象引用指向子类。
深拷贝会深度复制,如果某个属性为对象类型,那么他会复制出该对象的属性,再拷贝给子类。

//浅拷贝
function extend(parent, child) {
  var key;
  for(key in parent) {
    if (parent.hasOwnProperty(key)){
      child[key] = parent[key];
    }
  }
  return child;
}
​
//深拷贝
function extendDeep(parent, child) {
  var key;
  for(key in parent) {
    if (parent.hasOwnProperty(key)){
      if (typeof parent[key] === 'object') {
        child[key] = (parent[key].toString() === "[object Array]")? []:{};
        extendDeep(parent[key], child[key]);
      } else {
        child[key] = parent[key];
      }
    }
  }
  return child;
}

“借用方法”模式复用父类函数
如果不想实现父子自检的完全继承,仅仅期望子类实现父类中一个或多个方法,那么可以利用apply、call、bind来调用父类函数,实现复用。
parent.say.call(child, “hello, child!”);

@原型Prototype和原型链?
每个对象都有它的_proto_属性,并且指向它的prototype原型对象
每个构造函数都有哦一个prototype原型对象
每个prototype原型对象里面的constructor属性都指向构造函数本身。
实例对象的_prototype_指向构造函数的prototype属性,从而可以实现继承。

原型链:
每个对象都有一个_proto_属性,指向它的prototype原型对象,而该prototype原型对象又有他自己的prototype原型对象,一次层层网上查询知道prototype的原型对象为null,则该条查询路径为原型链

@闭包
闭包是函数和声明该函数的词法环境的组合。是指有权访问另一个函数作用域中的变量的函数。
有些情况下,函数调用完成之后,其执行上下文环境不会接着被销毁。使用闭包会增加内容开销。如果全局变量存在于函数中,函数被调用完后也不会被销毁。等到执行完全部才可以进行上下文环境的销毁。外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象。
闭包包含两种情况:
函数作为返回值,函数作为参数传递
创建一个闭包:
就是在一个函数内部创建另一个函数。
参考链接:http://www.cnblogs.com/wangfupeng1988/p/3977924.html

@运算符和=运算符的区别
==判定内容相同 ,等价于java的equals方法
=判断地址引用是否相同,等价于java的

面向对象:类的声明、类的集成(prototype)
原型对象
闭包:闭包就是一些局部变因为内存栈的无法及时释放,而产生的一种现象。
局部变量的作用域范围:局部变量的作用域范围是由函数体决定的
函数调用时变量栈的分配和释放
函数的返回值可以是反射

eval函数
alert(" “)//提示框
console.log(” ")//写到控制台
document.write(“ ”)//写到页面
现在$开头是合法的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值