几个小例子让你明白原型、继承、作用域

时间:2021-05-06 14:59:37

  今天整理电脑,发现了很多早些年初学js时,一些比较困惑的程序题。然后摘抄出了其中的一些,有关原型、继承、作用域等相关的。供初学者学习,其中若有我理解错误的,欢迎大家批评指正。
  下面不多说废话,直接上内容。


1、对象中属性或方法先从事例中寻找,若没有才去原型中寻找。

  function A () {}    
  function B(a) {       
    
this.a = a;     
  }   
  function C(a) {      
    
if (a) {        
      
this.a = a;      
    }    
  }  
  A.prototype.a
= 1
  B.prototype.a
= 1;
  C.prototype.a
= 1; 
  console.log(
new A().a); // 1      
  console.log(new B().a); // undefined     
  console.log(new C(2).a); // 2

2、原型链继承演示(简版)

  function Fn() {
    console.log(
1);
  }
  var fn = new Fn();
  console.log(fn);                             
// FN
  console.log(fn.__proto__ == Fn.prototype);              // true
  console.log(Fn.__proto__ == Function.prototype);          // true
  console.log(Function.prototype.__proto__ == Object.prototype); // true
  console.log(Object.prototype.__proto__);               // null 

3、ES6继承

  class Animal {
    constructor(){
      
this.type = 'animal'
    }
    says(say){
      console.log(
this.type + ' says ' + say)
    }
  }
  let animal
= new Animal()
  animal.says(
'hello')            // animal says hello
  console.log(animal.constructor);     // FUN Animal
  class Cat extends Animal {
    constructor(){
      super();
//修改this指向
      this.type = 'cat'
    }
  }
  let mini
= new Cat();

  console.log(mini.constructor
== Cat); // true 实例的constructor指向构造函数
  console.log(mini.type); // cat
  console.log(mini.__proto__ == Cat.prototype); // true
  console.log(Cat.prototype.__proto__ == Animal.prototype); // true
  console.log(Animal.prototype.__proto__ == Object.prototype);// true
  console.log(Object.prototype.__proto__); // true

4、作用域

1. 最近的作用域声明过,则去就近取
  
var tt = "a";
  
function test(){
    
//函数内部作用域声明过,所以会就近取。var 有声明提升。
    //
相当于在本作用域前声明
    console.log(tt); // undefined
    var tt = "b"
    console.log(tt);
// b
  }
  test();

  
function test2(){
    
//函数内部作用域没有声明过,
    //
直接从外部取值,调用。
    console.log(tt); // a
  }
  test2();

2. 作用域发生变化
  
var length = "aaa"               //若注释这句, window的length就为0
  function fn(){
    console.log(
this.length);
  }
  
var obj = {
    length:
"bbb",
    test:
function(fn){
      fn();                   
// aaa      this 为 window
      console.log(this.length);       ·// bbb      this 为 obj
      arguments[0]();             // 1       this 为 arguments 对象 arguments的length为1
    }
  }
  obj.test(fn);
3. this 指向
  
function fn(a,b){
    alert(
this+","+a);
  }
  fn.call(
"web",4,10)        // web,4

  var _name = "window name";
  
var hero = {
    _name:
"John Doe",
    getName:
function(){
      
return this._name;
    }
  }
  
var st=hero.getName;
  console.log(st());             
// window name 此处this为window
  console.log(hero.getName())        // John Doe 此处this为hero对象

4. 原型,继承
  
function SuperType(){
    
this.car="宝马";
    
this.home="大别墅";
  }
  
function SubType(){

  }

  SubType.prototype
=new SuperType()
  
var pp=new SubType()
  console.log(pp.car)           
// 宝马

5. 函数别名作用域

  var func = function a (){
    console.log(
typeof a); // function
  }
  func();
  console.log(
typeof a) // undefined

  // 在函数内部可以找到a,
  //
但在外部a不存在,只有func;

6. 函数内修改值
  
var a = 1;
  
var obj = {b:2};
  
var fn = function(){};
  fn.c
= 3;
  
function test(x,y,z){
    x
= 4;
    y.b
= 5;
    z.c
= 6;
    
return z
  }
  test(a,obj,fn);
  console.log(a
+obj.b+fn.c); // 12 1, 5, 6

  // 在函数内部,若直接修改参数的值,该值不会传递在外部,
  //
但修改参数内部的某属性时,则可以改变

7. 作用域优先级问题
  
var a = 1;
  
function fn(a){
    console.log(a);
    
var a = 3;
    
function a (){};
  }
  fn(
2); // function

  // 函数作用域同名变量,函数优先打印出来,其次是参数,再然后是局部变量,最后是全局变量。
  //
那么意味着,暂且抛开全局变量不谈,局部变量 var 先声明提升,再然后是参数,最后是函数。
  //
所以在程序开始运行的时候只能找到函数的值。
  //
可能语言描述不清,看例子即可。

  // 若注释 function a (){}; 打印值为 2
  var a = 1;
  
function fn(a){
    console.log(a);
    
var a = 3;
  }
  fn(
2);       // 2

  // 若再去掉参数 打印值为 undefined 声明提升。
  var a = 1;
  
function fn(){
  console.log(a);
    
var a = 3;
  }
  fn();

  
// 若再去掉var a = 3; 打印值为 1
  var a = 1;
  
function fn(){
    console.log(a);
  }
  fn();

  
// 整体声明提升遵循这样一个规律, 局部变量 var > 参数 > 函数

  好了,今天就暂时分享到这里。